aboutsummaryrefslogtreecommitdiffstats
path: root/ice_validator/tests
diff options
context:
space:
mode:
authorstark, steven <steven.stark@att.com>2019-05-13 14:41:55 -0700
committerstark, steven <steven.stark@att.com>2019-05-13 14:41:55 -0700
commit503041fb7ec395fe57e418d584c4a5d06f4c9877 (patch)
tree5e7f56bd44ddf7324888cd59442da96321edc235 /ice_validator/tests
parent43385d805115d53603a5643462aebb3fa1152de2 (diff)
[VVP] Adding tests for new reqs from VNFRQTS-630
Added tests for reqs: R-100010, R-100030, R-100050, R-100070, R-100090, R-100110, R-100130, R-100150, R-100200, R-100220, R-100240, R-100310, R-100330, R-100360, R-100370, R-100260, R-100000, R-100190, R-100350 Updated neutron param tests to re-use validation code for contrail tests Change-Id: I84af725ca9de176dc690fffda01ffcad453213ea Issue-ID: VVP-211 Signed-off-by: stark, steven <steven.stark@att.com>
Diffstat (limited to 'ice_validator/tests')
-rw-r--r--ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/fail/fail.yaml42
-rw-r--r--ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/pass/pass.yaml42
-rw-r--r--ice_validator/tests/fixtures/test_contrail_instance_ip_resource_id/fail/fail0.yaml2
-rw-r--r--ice_validator/tests/fixtures/test_contrail_vmi_parameters/fail/fail.yaml65
-rw-r--r--ice_validator/tests/fixtures/test_contrail_vmi_parameters/pass/pass.yaml65
-rw-r--r--ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml20
-rw-r--r--ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml6
-rw-r--r--ice_validator/tests/helpers.py8
-rw-r--r--ice_validator/tests/structures.py82
-rw-r--r--ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py11
-rw-r--r--ice_validator/tests/test_contrail_instance_ip_parameters.py133
-rw-r--r--ice_validator/tests/test_contrail_instance_ip_resource_id.py11
-rw-r--r--ice_validator/tests/test_contrail_vmi_parameters.py99
-rw-r--r--ice_validator/tests/test_contrail_vmi_resource_id.py4
-rw-r--r--ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py7
-rw-r--r--ice_validator/tests/test_nested_parameters.py3
-rw-r--r--ice_validator/tests/test_neutron_port_fixed_ips_subnet.py32
-rw-r--r--ice_validator/tests/utils/ports.py186
18 files changed, 599 insertions, 219 deletions
diff --git a/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/fail/fail.yaml b/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/fail/fail.yaml
new file mode 100644
index 0000000..d7770d7
--- /dev/null
+++ b/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/fail/fail.yaml
@@ -0,0 +1,42 @@
+heat_template_version: 2015-04-30
+
+description: fdsafsfsa
+
+parameters:
+
+ TESTDB_int_priav_ips:
+ type: comma_delimited_list
+ description: asnfjl
+
+ TESTDB_private_ips:
+ type: string
+ description: asnfjl
+
+ priv_subnet_id:
+ type: string
+ description: asnfjl
+
+ privte_v6_subnet_id:
+ type: string
+ description: asnfjl
+
+resources:
+
+ TESTDB_0_int_priv_vmi_0_IP_0:
+ type: OS::ContrailV2::InstanceIp
+ properties:
+ virtual_machine_interface_refs: { get_resource: TESTDB_0_priv_vmi_0 }
+ virtual_network_refs: [{ get_resource: int_priv_network }]
+ instance_ip_address: { get_param: [TESTDB_int_priav_ips, 0] }
+ subnet_uuid: { get_param: priv_subnet_id }
+
+ TESTDB_0_private_vmi_1_IP_0:
+ type: OS::ContrailV2::InstanceIp
+ properties:
+ virtual_machine_interface_refs: { get_resource: TESTDB_1_priv_vmi_0 }
+ virtual_network_refs: [{ get_param: priv_net_fqdn }]
+ instance_ip_address: { get_param: [TESTDB_private_ips, 1] }
+ subnet_uuid: { get_param: privte_v6_subnet_id }
+
+ #testnlksadf:
+ # type: http://www.google.com
diff --git a/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/pass/pass.yaml b/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/pass/pass.yaml
new file mode 100644
index 0000000..8645348
--- /dev/null
+++ b/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/pass/pass.yaml
@@ -0,0 +1,42 @@
+heat_template_version: 2015-04-30
+
+description: fdsafsfsa
+
+parameters:
+
+ TESTDB_int_priv_ips:
+ type: comma_delimited_list
+ description: asnfjl
+
+ TESTDB_private_ips:
+ type: comma_delimited_list
+ description: asnfjl
+
+ int_priv_subnet_id:
+ type: string
+ description: asnfjl
+
+ private_v6_subnet_id:
+ type: string
+ description: asnfjl
+
+resources:
+
+ TESTDB_0_int_priv_vmi_0_IP_0:
+ type: OS::ContrailV2::InstanceIp
+ properties:
+ virtual_machine_interface_refs: { get_resource: TESTDB_0_priv_vmi_0 }
+ virtual_network_refs: [{ get_resource: int_priv_network }]
+ instance_ip_address: { get_param: [TESTDB_int_priv_ips, 0] }
+ subnet_uuid: { get_param: int_priv_subnet_id }
+
+ TESTDB_0_private_vmi_1_IP_0:
+ type: OS::ContrailV2::InstanceIp
+ properties:
+ virtual_machine_interface_refs: { get_resource: TESTDB_1_priv_vmi_0 }
+ virtual_network_refs: [{ get_param: priv_net_fqdn }]
+ instance_ip_address: { get_param: [TESTDB_private_ips, 1] }
+ subnet_uuid: { get_param: private_v6_subnet_id }
+
+ #testnlksadf:
+ # type: http://www.google.com
diff --git a/ice_validator/tests/fixtures/test_contrail_instance_ip_resource_id/fail/fail0.yaml b/ice_validator/tests/fixtures/test_contrail_instance_ip_resource_id/fail/fail0.yaml
index a5f5e16..92bdb35 100644
--- a/ice_validator/tests/fixtures/test_contrail_instance_ip_resource_id/fail/fail0.yaml
+++ b/ice_validator/tests/fixtures/test_contrail_instance_ip_resource_id/fail/fail0.yaml
@@ -42,7 +42,7 @@
resources:
- vm_typeS_0_bialy_port_0:
+ vm_typeS_0_int_bialy_port_0:
type: OS::ContrailV2::InstanceIp
properties:
virtual_network_refs:
diff --git a/ice_validator/tests/fixtures/test_contrail_vmi_parameters/fail/fail.yaml b/ice_validator/tests/fixtures/test_contrail_vmi_parameters/fail/fail.yaml
new file mode 100644
index 0000000..248f9ec
--- /dev/null
+++ b/ice_validator/tests/fixtures/test_contrail_vmi_parameters/fail/fail.yaml
@@ -0,0 +1,65 @@
+heat_template_version: 2015-04-30
+
+description: fdsafsfsa
+
+parameters:
+
+ TESTDB_priv_floating_ips:
+ type: comma_delimited_list
+ description: asnfjl
+
+ TESTDB_int_priav_floating_ip:
+ type: string
+ description: asnfjl
+
+resources:
+
+ TESTDB_0_priv_vmi_0:
+ type: OS::ContrailV2::VirtualMachineInterface
+ properties:
+ virtual_machine_interface_properties:
+ virtual_machine_interface_properties_service_interface_type: {
+ "priv_interface_type"
+ }
+ virtual_network_refs:
+ - get_param: priv_net_fqdn
+ virtual_machine_interface_allowed_address_pairs:
+ {
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair:
+ [{
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip:
+ {
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix: { get_param: [TESTDB_priv_floating_ip, 0] },
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix_len: "dsafasdF",
+ },
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_mac: "sdnfjkas",
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_address_mode: "sadfnjasdfknj",
+ }],
+ }
+
+
+ TESTDB_0_int_private_vmi_0:
+ type: OS::ContrailV2::VirtualMachineInterface
+ properties:
+ virtual_machine_interface_properties:
+ virtual_machine_interface_properties_service_interface_type: {
+ "priv_interface_type"
+ }
+ virtual_network_refs:
+ - get_param: priv_net_fqdn
+ virtual_machine_interface_allowed_address_pairs:
+ {
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair:
+ [{
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip:
+ {
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix: { get_param: TESTDB_int_priav_floating_ip },
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix_len: "dsafasdF",
+ },
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_mac: "sdnfjkas",
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_address_mode: "sadfnjasdfknj",
+ }],
+ }
+
+ #testnlksadf:
+ # type: http://www.google.com
diff --git a/ice_validator/tests/fixtures/test_contrail_vmi_parameters/pass/pass.yaml b/ice_validator/tests/fixtures/test_contrail_vmi_parameters/pass/pass.yaml
new file mode 100644
index 0000000..df4ca00
--- /dev/null
+++ b/ice_validator/tests/fixtures/test_contrail_vmi_parameters/pass/pass.yaml
@@ -0,0 +1,65 @@
+heat_template_version: 2015-04-30
+
+description: fdsafsfsa
+
+parameters:
+
+ TESTDB_priv_floating_ip:
+ type: string
+ description: asnfjl
+
+ TESTDB_int_private_floating_ips:
+ type: comma_delimited_list
+ description: asnfjl
+
+resources:
+
+ TESTDB_0_priv_vmi_0:
+ type: OS::ContrailV2::VirtualMachineInterface
+ properties:
+ virtual_machine_interface_properties:
+ virtual_machine_interface_properties_service_interface_type: {
+ "priv_interface_type"
+ }
+ virtual_network_refs:
+ - get_param: priv_net_fqdn
+ virtual_machine_interface_allowed_address_pairs:
+ {
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair:
+ [{
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip:
+ {
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix: { get_param: TESTDB_priv_floating_ip },
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix_len: "dsafasdF",
+ },
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_mac: "sdnfjkas",
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_address_mode: "sadfnjasdfknj",
+ }],
+ }
+
+
+ TESTDB_0_int_private_vmi_0:
+ type: OS::ContrailV2::VirtualMachineInterface
+ properties:
+ virtual_machine_interface_properties:
+ virtual_machine_interface_properties_service_interface_type: {
+ "priv_interface_type"
+ }
+ virtual_network_refs:
+ - get_param: priv_net_fqdn
+ virtual_machine_interface_allowed_address_pairs:
+ {
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair:
+ [{
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip:
+ {
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix: { get_param: [TESTDB_int_private_floating_ips, 0] },
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix_len: "dsafasdF",
+ },
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_mac: "sdnfjkas",
+ virtual_machine_interface_allowed_address_pairs_allowed_address_pair_address_mode: "sadfnjasdfknj",
+ }],
+ }
+
+ #testnlksadf:
+ # type: http://www.google.com
diff --git a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml
index 901072f..de509a2 100644
--- a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml
+++ b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml
@@ -51,6 +51,8 @@ parameters:
type: comma_delimited_list
subnet_param:
type: comma_delimited_list
+ int_subnet_param:
+ type: comma_delimited_list
subnet_id_param:
type: comma_delimited_list
@@ -92,3 +94,21 @@ resources:
metadata:
port_type: SR-IOV_Mirrored_Trunk
+ vm_typeX_3_int_bialy_port_2:
+ type: OS::Neutron::Port
+ properties:
+ network: { get_param: extnet_net_id }
+ fixed_ips:
+ - ip_address: { get_param: lb_2_extnet_floating_v6_ip }
+ subnet: { get_param: int_subnet_param }
+ binding:vnic_type: direct
+ value_specs:
+ vlan_filter: {get_param: vm_typeX_bialy_vlan_filter}
+ public_vlans: {get_param: vm_typeX_bialy_public_vlans}
+ private_vlans: {get_param: vm_typeX_bialy_private_vlans}
+ guest_vlans: {get_param: vm_typeX_bialy_guest_vlans}
+ vlan_mirror:
+ ATT_FABRIC_CONFIGURATION_REQUIRED: true
+ metadata:
+ port_type: SR-IOV_Mirrored_Trunk
+
diff --git a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml
index 60f9874..9233707 100644
--- a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml
+++ b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml
@@ -53,6 +53,8 @@ parameters:
type: comma_delimited_list
bialy_subnet_id:
type: string
+ int_biay_subnet_id:
+ type: string
resources:
@@ -74,13 +76,13 @@ resources:
metadata:
port_type: SR-IOV_Trunk
- vm_typeX_3_bialy_port_2:
+ vm_typeX_3_int_bialy_port_2:
type: OS::Neutron::Port
properties:
network: { get_param: extnet_net_id }
fixed_ips:
- ip_address: { get_param: lb_2_extnet_floating_v6_ip }
- subnet: { get_param: bialy_susbnet }
+ subnet: { get_param: int_biay_subnet_id }
binding:vnic_type: direct
value_specs:
vlan_filter: {get_param: vm_typeX_bialy_vlan_filter}
diff --git a/ice_validator/tests/helpers.py b/ice_validator/tests/helpers.py
index afa8672..c73a118 100644
--- a/ice_validator/tests/helpers.py
+++ b/ice_validator/tests/helpers.py
@@ -310,17 +310,17 @@ def parameter_type_to_heat_type(parameter):
def prop_iterator(resource, *props):
- terminators = ["get_resource", "get_attr", "str_replace"]
+ terminators = ["get_resource", "get_attr", "str_replace", "get_param"]
if "properties" in resource:
resource = resource.get("properties")
props = list(props)
- if isinstance(resource, dict) and "get_param" in resource:
- yield resource.get("get_param")
+ if isinstance(resource, dict) and any(x for x in terminators if x in resource):
+ yield resource
else:
prop = resource.get(props.pop(0))
if isinstance(prop, list):
for x in prop:
yield from prop_iterator(x, *props)
- elif isinstance(prop, dict) and not any(x for x in terminators if x in prop):
+ elif isinstance(prop, dict):
yield from prop_iterator(prop, *props)
diff --git a/ice_validator/tests/structures.py b/ice_validator/tests/structures.py
index a6b2015..8abe87b 100644
--- a/ice_validator/tests/structures.py
+++ b/ice_validator/tests/structures.py
@@ -229,7 +229,7 @@ class ContrailV2NetworkFlavorBaseProcessor(HeatProcessor):
network_flavor_external = "external"
network_flavor_internal = "internal"
- network_flavor_subint = "subint"
+ network_flavor_subint = "subinterface"
@classmethod
def get_network_flavor(cls, resource):
@@ -270,7 +270,7 @@ class ContrailV2InstanceIpProcessor(ContrailV2NetworkFlavorBaseProcessor):
re_rids = collections.OrderedDict(
[
(
- "int_ip",
+ "internal",
_get_regex(
r"(?P<vm_type>.+)"
r"_(?P<vm_type_index>\d+)"
@@ -278,27 +278,14 @@ class ContrailV2InstanceIpProcessor(ContrailV2NetworkFlavorBaseProcessor):
r"_(?P<network_role>.+)"
r"_vmi"
r"_(?P<vmi_index>\d+)"
+ r"(_v6)?"
r"_IP"
r"_(?P<index>\d+)"
r"$"
),
),
(
- "int_v6_ip",
- _get_regex(
- r"(?P<vm_type>.+)"
- r"_(?P<vm_type_index>\d+)"
- r"_int"
- r"_(?P<network_role>.+)"
- r"_vmi"
- r"_(?P<vmi_index>\d+)"
- r"_v6_IP"
- r"_(?P<index>\d+)"
- r"$"
- ),
- ),
- (
- "subint_ip",
+ "subinterface",
_get_regex(
r"(?P<vm_type>.+)"
r"_(?P<vm_type_index>\d+)"
@@ -306,51 +293,26 @@ class ContrailV2InstanceIpProcessor(ContrailV2NetworkFlavorBaseProcessor):
r"_(?P<network_role>.+)"
r"_vmi"
r"_(?P<vmi_index>\d+)"
+ r"(_v6)?"
r"_IP"
r"_(?P<index>\d+)"
r"$"
),
),
(
- "subint_v6_ip",
- _get_regex(
- r"(?P<vm_type>.+)"
- r"_(?P<vm_type_index>\d+)"
- r"_subint"
- r"_(?P<network_role>.+)"
- r"_vmi"
- r"_(?P<vmi_index>\d+)"
- r"_v6_IP"
- r"_(?P<index>\d+)"
- r"$"
- ),
- ),
- (
- "ip",
+ "external",
_get_regex(
r"(?P<vm_type>.+)"
r"_(?P<vm_type_index>\d+)"
r"_(?P<network_role>.+)"
r"_vmi"
r"_(?P<vmi_index>\d+)"
+ r"(_v6)?"
r"_IP"
r"_(?P<index>\d+)"
r"$"
),
),
- (
- "v6_ip",
- _get_regex(
- r"(?P<vm_type>.+)"
- r"_(?P<vm_type_index>\d+)"
- r"_(?P<network_role>.+)"
- r"_vmi"
- r"_(?P<vmi_index>\d+)"
- r"_v6_IP"
- r"_(?P<index>\d+)"
- r"$"
- ),
- ),
]
)
@@ -412,7 +374,7 @@ class ContrailV2VirtualMachineInterfaceProcessor(ContrailV2NetworkFlavorBaseProc
re_rids = collections.OrderedDict(
[
(
- "vmi_internal",
+ "internal",
_get_regex(
r"(?P<vm_type>.+)"
r"_(?P<vm_type_index>\d+)"
@@ -424,7 +386,7 @@ class ContrailV2VirtualMachineInterfaceProcessor(ContrailV2NetworkFlavorBaseProc
),
),
(
- "vmi_subint",
+ "subinterface",
_get_regex(
r"(?P<vm_type>.+)"
r"_(?P<vm_type_index>\d+)"
@@ -436,7 +398,7 @@ class ContrailV2VirtualMachineInterfaceProcessor(ContrailV2NetworkFlavorBaseProc
),
),
(
- "vmi_external",
+ "external",
_get_regex(
r"(?P<vm_type>.+)"
r"_(?P<vm_type_index>\d+)"
@@ -504,7 +466,7 @@ class NeutronPortProcessor(HeatProcessor):
re_rids = collections.OrderedDict(
[
(
- "internal_port",
+ "internal",
_get_regex(
r"(?P<vm_type>.+)"
r"_(?P<vm_type_index>\d+)"
@@ -515,7 +477,7 @@ class NeutronPortProcessor(HeatProcessor):
),
),
(
- "port",
+ "external",
_get_regex(
r"(?P<vm_type>.+)"
r"_(?P<vm_type_index>\d+)"
@@ -524,26 +486,6 @@ class NeutronPortProcessor(HeatProcessor):
r"$"
),
),
- (
- "floating_ip",
- _get_regex(
- r"reserve_port"
- r"_(?P<vm_type>.+)"
- r"_(?P<network_role>.+)"
- r"_floating_ip_(?P<index>\d+)"
- r"$"
- ),
- ),
- (
- "floating_v6_ip",
- _get_regex(
- r"reserve_port"
- r"_(?P<vm_type>.+)"
- r"_(?P<network_role>.+)"
- r"_floating_v6_ip_(?P<index>\d+)"
- r"$"
- ),
- ),
]
)
diff --git a/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py b/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py
index 4654333..76e5f18 100644
--- a/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py
+++ b/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py
@@ -39,7 +39,8 @@
import re
from .helpers import validates
-from .utils.ports import check_ip_format
+from .utils.ports import check_parameter_format
+from tests.structures import NeutronPortProcessor
VERSION = "1.0.0"
@@ -80,13 +81,13 @@ aap_regx_dict = {
@validates("R-41492", "R-35735", "R-159016")
def test_external_aap_format(yaml_file):
- check_ip_format(
- yaml_file, aap_regx_dict, "external", "allowed_address_pairs", "ip_address"
+ check_parameter_format(
+ yaml_file, aap_regx_dict, "external", NeutronPortProcessor, "allowed_address_pairs", "ip_address"
)
@validates("R-717227", "R-805572")
def test_internal_aap_format(yaml_file):
- check_ip_format(
- yaml_file, aap_regx_dict, "internal", "allowed_address_pairs", "ip_address"
+ check_parameter_format(
+ yaml_file, aap_regx_dict, "internal", NeutronPortProcessor, "allowed_address_pairs", "ip_address"
)
diff --git a/ice_validator/tests/test_contrail_instance_ip_parameters.py b/ice_validator/tests/test_contrail_instance_ip_parameters.py
new file mode 100644
index 0000000..a708a58
--- /dev/null
+++ b/ice_validator/tests/test_contrail_instance_ip_parameters.py
@@ -0,0 +1,133 @@
+# -*- coding: utf8 -*-
+# ============LICENSE_START====================================================
+# org.onap.vvp/validation-scripts
+# ===================================================================
+# Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+# ===================================================================
+#
+# Unless otherwise specified, all software contained herein is licensed
+# under the Apache License, Version 2.0 (the "License");
+# you may not use this software except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+#
+# Unless otherwise specified, all documentation contained herein is licensed
+# under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+# you may not use this documentation except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://creativecommons.org/licenses/by/4.0/
+#
+# Unless required by applicable law or agreed to in writing, documentation
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ============LICENSE_END============================================
+#
+#
+import re
+
+from tests.structures import ContrailV2InstanceIpProcessor
+from tests.helpers import validates
+from tests.utils.ports import check_parameter_format
+
+RE_EXTERNAL_PARAM_IIP = re.compile( # match pattern
+ r"(?P<vm_type>.+)_(?P<network_role>.+?)(_v6)?_ip_(?P<ip_index>.+)$"
+)
+
+RE_EXTERNAL_PARAM_IIPS = re.compile( # match pattern
+ r"(?P<vm_type>.+)_(?P<network_role>.+?)(_v6)?_ips$"
+)
+
+RE_INTERNAL_PARAM_IIP = re.compile( # match pattern
+ r"(?P<vm_type>.+)_int_(?P<network_role>.+?)(_v6)?_ip_(?P<ip_index>.+)$"
+)
+
+RE_INTERNAL_PARAM_IIPS = re.compile( # match pattern
+ r"(?P<vm_type>.+)_int_(?P<network_role>.+?)(_v6)?_ips$"
+)
+
+iip_regx_dict = {
+ "external": {
+ "string": {
+ "readable": "{vm-type}_{network-role}_ip_{ip-index} or {vm-type}_{network-role}_v6_ip_{ip-index}",
+ "machine": RE_EXTERNAL_PARAM_IIP,
+ },
+ "comma_delimited_list": {
+ "readable": "{vm-type}_{network-role}_ips or {vm-type}_{network-role}_v6_ips",
+ "machine": RE_EXTERNAL_PARAM_IIPS,
+ },
+ },
+ "internal": {
+ "string": {
+ "readable": "{vm-type}_int_{network-role}_ip_{ip-index} or {vm-type}_int_{network-role}_v6_ip_{ip-index}",
+ "machine": RE_INTERNAL_PARAM_IIP,
+ },
+ "comma_delimited_list": {
+ "readable": "{vm-type}_int_{network-role}_ips or {vm-type}_int_{network-role}_v6_ips",
+ "machine": RE_INTERNAL_PARAM_IIPS,
+ },
+ },
+ "parameter_to_resource_comparisons": ["vm_type", "network_role"],
+}
+
+
+RE_EXTERNAL_PARAM_SID = re.compile( # match pattern
+ r"(?P<network_role>.+?)(_v6)?_subnet_id$"
+)
+
+RE_INTERNAL_PARAM_SID = re.compile( # match pattern
+ r"int_(?P<network_role>.+?)(_v6)?_subnet_id$"
+)
+
+sid_regx_dict = {
+ "external": {
+ "string": {
+ "readable": "{network-role}_subnet_id or {network-role}_v6_subnet_id",
+ "machine": RE_EXTERNAL_PARAM_SID,
+ },
+ },
+ "internal": {
+ "string": {
+ "readable": "int_{network-role}_subnet_id or int_{network-role}_v6_subnet_id",
+ "machine": RE_INTERNAL_PARAM_SID,
+ },
+ },
+ "parameter_to_resource_comparisons": ["network_role"],
+}
+
+
+@validates("R-100000", "R-100010", "R-100030", "R-100150", "R-100070")
+def test_contrail_external_instance_ip_address_parameter(yaml_file):
+ check_parameter_format(yaml_file, iip_regx_dict, "external", ContrailV2InstanceIpProcessor, "instance_ip_address")
+
+
+@validates("R-100000", "R-100090", "R-100110", "R-100130", "R-100180")
+def test_contrail_internal_instance_ip_address_parameter(yaml_file):
+ check_parameter_format(yaml_file, iip_regx_dict, "internal", ContrailV2InstanceIpProcessor, "instance_ip_address")
+
+
+@validates("R-100190", "R-100200", "R-100220")
+def test_contrail_external_instance_subnet_id_parameter(yaml_file):
+ check_parameter_format(yaml_file, sid_regx_dict, "external", ContrailV2InstanceIpProcessor, "subnet_uuid")
+
+
+@validates("R-100190", "R-100240", "R-100260")
+def test_contrail_internal_instance_subnet_id_parameter(yaml_file):
+ check_parameter_format(yaml_file, sid_regx_dict, "internal", ContrailV2InstanceIpProcessor, "subnet_uuid")
+
+
+
+
+
diff --git a/ice_validator/tests/test_contrail_instance_ip_resource_id.py b/ice_validator/tests/test_contrail_instance_ip_resource_id.py
index 5e80075..2833d5b 100644
--- a/ice_validator/tests/test_contrail_instance_ip_resource_id.py
+++ b/ice_validator/tests/test_contrail_instance_ip_resource_id.py
@@ -36,10 +36,6 @@
# ============LICENSE_END============================================
#
#
-"""
-resources:
-{vm-type}_server_{vm-type_index}
-"""
import pytest
from .structures import Heat
@@ -64,8 +60,9 @@ def run_test(heat_template, regex_names, network_flavor):
flavor = processor.get_network_flavor(resource)
if flavor != network_flavor:
continue
+
regex_name = processor.get_rid_match_tuple(rid)[0]
- if regex_name in regex_names:
+ if regex_name and regex_name in regex_names:
continue
bad.append(rid)
assert not bad, "%s resource ids %s must match one of %s" % (
@@ -101,7 +98,7 @@ def test_contrail_instance_ip_resource_id_external(yaml_file):
run_test(
yaml_file,
- regex_names=("ip", "v6_ip"),
+ regex_names=("external"),
network_flavor=ContrailV2InstanceIpProcessor.network_flavor_external,
)
@@ -117,6 +114,6 @@ def test_contrail_instance_ip_resource_id_internal(yaml_file):
"""
run_test(
yaml_file,
- regex_names=("int_ip", "int_v6_ip"),
+ regex_names=("internal"),
network_flavor=ContrailV2InstanceIpProcessor.network_flavor_internal,
)
diff --git a/ice_validator/tests/test_contrail_vmi_parameters.py b/ice_validator/tests/test_contrail_vmi_parameters.py
new file mode 100644
index 0000000..311e352
--- /dev/null
+++ b/ice_validator/tests/test_contrail_vmi_parameters.py
@@ -0,0 +1,99 @@
+# -*- coding: utf8 -*-
+# ============LICENSE_START====================================================
+# org.onap.vvp/validation-scripts
+# ===================================================================
+# Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+# ===================================================================
+#
+# Unless otherwise specified, all software contained herein is licensed
+# under the Apache License, Version 2.0 (the "License");
+# you may not use this software except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+#
+# Unless otherwise specified, all documentation contained herein is licensed
+# under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+# you may not use this documentation except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://creativecommons.org/licenses/by/4.0/
+#
+# Unless required by applicable law or agreed to in writing, documentation
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ============LICENSE_END============================================
+#
+#
+import re
+
+from tests.structures import ContrailV2VirtualMachineInterfaceProcessor
+from tests.helpers import validates
+from tests.utils.ports import check_parameter_format
+
+RE_EXTERNAL_PARAM_AAP = re.compile( # match pattern
+ r"(?P<vm_type>.+)_(?P<network_role>.+)_floating(_v6)?_ip$"
+)
+
+RE_INTERNAL_PARAM_AAP = re.compile( # match pattern
+ r"(?P<vm_type>.+)_int_(?P<network_role>.+)_floating(_v6)?_ip$"
+)
+
+RE_INTERNAL_PARAM_AAPS = re.compile( # match pattern
+ r"(?P<vm_type>.+)_int_(?P<network_role>.+)_floating(_v6)?_ips$"
+)
+
+aap_regx_dict = {
+ "external": {
+ "string": {
+ "readable": "{vm-type}_{network-role}_floating_ip or {vm-type}_{network-role}_floating_v6_ip",
+ "machine": RE_EXTERNAL_PARAM_AAP,
+ }
+ },
+ "internal": {
+ "string": {
+ "readable": "{vm-type}_int_{network-role}_floating_ip or {vm-type}_int_{network-role}_floating_v6_ip",
+ "machine": RE_INTERNAL_PARAM_AAP,
+ },
+ "comma_delimited_list": {
+ "readable": "{vm-type}_int_{network-role}_floating_ips or {vm-type}_int_{network-role}_floating_v6_ips",
+ "machine": RE_INTERNAL_PARAM_AAPS,
+ },
+ },
+ "parameter_to_resource_comparisons": ["vm_type", "network_role"],
+}
+
+
+@validates("R-100310", "R-100330", "R-100350")
+def test_contrail_external_vmi_aap_parameter(yaml_file):
+ check_parameter_format(yaml_file,
+ aap_regx_dict,
+ "external",
+ ContrailV2VirtualMachineInterfaceProcessor,
+ "virtual_machine_interface_allowed_address_pairs",
+ "virtual_machine_interface_allowed_address_pairs_allowed_address_pair",
+ "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip",
+ "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix")
+
+
+@validates("R-100360", "R-100370")
+def test_contrail_internal_vmi_aap_parameter(yaml_file):
+ check_parameter_format(yaml_file,
+ aap_regx_dict,
+ "internal",
+ ContrailV2VirtualMachineInterfaceProcessor,
+ "virtual_machine_interface_allowed_address_pairs",
+ "virtual_machine_interface_allowed_address_pairs_allowed_address_pair",
+ "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip",
+ "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix")
diff --git a/ice_validator/tests/test_contrail_vmi_resource_id.py b/ice_validator/tests/test_contrail_vmi_resource_id.py
index 9cabfb4..ed8f87d 100644
--- a/ice_validator/tests/test_contrail_vmi_resource_id.py
+++ b/ice_validator/tests/test_contrail_vmi_resource_id.py
@@ -92,7 +92,7 @@ def test_contrail_instance_ip_resource_id_external(yaml_file):
"""
run_test(
yaml_file,
- regex_name="vmi_external",
+ regex_name="external",
network_flavor=ContrailV2VirtualMachineInterfaceProcessor.network_flavor_external,
)
@@ -109,6 +109,6 @@ def test_contrail_instance_ip_resource_id_internal(yaml_file):
"""
run_test(
yaml_file,
- regex_name="vmi_internal",
+ regex_name="internal",
network_flavor=ContrailV2VirtualMachineInterfaceProcessor.network_flavor_internal,
)
diff --git a/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py b/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py
index 4c62528..2ce1bcf 100644
--- a/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py
+++ b/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py
@@ -40,7 +40,8 @@
import re
from .helpers import validates
-from .utils.ports import check_ip_format
+from .utils.ports import check_parameter_format
+from tests.structures import NeutronPortProcessor
RE_EXTERNAL_PARAM_FIP = re.compile( # match pattern
@@ -86,9 +87,9 @@ fip_regx_dict = {
@validates("R-40971", "R-35735", "R-23503", "R-71577", "R-04697", "R-34037")
def test_external_fip_format(yaml_file):
- check_ip_format(yaml_file, fip_regx_dict, "external", "fixed_ips", "ip_address")
+ check_parameter_format(yaml_file, fip_regx_dict, "external", NeutronPortProcessor, "fixed_ips", "ip_address")
@validates("R-27818", "R-29765", "R-85235", "R-78380", "R-34037")
def test_internal_fip_format(yaml_file):
- check_ip_format(yaml_file, fip_regx_dict, "internal", "fixed_ips", "ip_address")
+ check_parameter_format(yaml_file, fip_regx_dict, "internal", NeutronPortProcessor, "fixed_ips", "ip_address")
diff --git a/ice_validator/tests/test_nested_parameters.py b/ice_validator/tests/test_nested_parameters.py
index 846a977..47c4d90 100644
--- a/ice_validator/tests/test_nested_parameters.py
+++ b/ice_validator/tests/test_nested_parameters.py
@@ -90,7 +90,8 @@ def check_nested_parameter_doesnt_change(yaml_file, nresource_type, *nprops):
continue
for nparam in prop_iterator(nresource_dict, *nprops): # get iterator of all target parameters
- if nparam: # iterator yields None if parameter isn't found
+ if nparam and "get_param" in nparam: # iterator yields None if parameter isn't found
+ nparam = nparam.get("get_param")
for k1, v1 in properties.items(): # found nparam, now comparing to parent template
if isinstance(v1, dict) and "get_param" in v1:
parameter = v1.get("get_param")
diff --git a/ice_validator/tests/test_neutron_port_fixed_ips_subnet.py b/ice_validator/tests/test_neutron_port_fixed_ips_subnet.py
index 1df7aac..a07225b 100644
--- a/ice_validator/tests/test_neutron_port_fixed_ips_subnet.py
+++ b/ice_validator/tests/test_neutron_port_fixed_ips_subnet.py
@@ -36,31 +36,6 @@
# ============LICENSE_END============================================
#
#
-
-"""
-resources:
-{vm-type}_{vm-type_index}_{network-role}_port_{port-index}:
- type: OS::Neutron::Port
- properties:
- network: { get_param: ...}
- fixed_ips: [ { "ipaddress": { get_param: ... } } ]
- binding:vnic_type: direct #only SR-IOV ports, not OVS ports
- value_specs: {
- vlan_filter: { get_param: ... }, #all NC ports
- public_vlans: { get_param: ... }, #all NC ports
- private_vlans: { get_param: ... },#all NC ports
- guest_vlans: { get_param: ... }, #SR-IOV Trunk Port only
- vlan_mirror: { get_param: ... }, #SRIOV Trunk Port
- # Receiving Mirrored Traffic only
- ATT_FABRIC_CONFIGURATION_REQUIRED: true #all NC ports
- }
- metadata:
- port_type: SR-IOV_Trunk #SR-IOV Trunk Port
- port_type: SR-IOV_Non_Trunk #SR-IOV Non Trunk Port
- port_type: OVS #OVS Port
- port_type: SR-IOV_Mirrored_Trunk #SR-IOV Trunk Port
- # Receiving Mirrored Traffic
-"""
import re
from tests.utils.network_roles import get_network_type_from_port
@@ -68,7 +43,8 @@ from tests.parametrizers import get_nested_files
from .structures import Heat
from .helpers import validates, load_yaml, get_base_template_from_yaml_files
-from .utils.ports import check_ip_format
+from .utils.ports import check_parameter_format
+from tests.structures import NeutronPortProcessor
VERSION = "1.3.0"
@@ -99,12 +75,12 @@ fip_regx_dict = {
@validates("R-38236", "R-84123", "R-76160")
def test_internal_subnet_format(yaml_file):
- check_ip_format(yaml_file, fip_regx_dict, "internal", "fixed_ips", "subnet")
+ check_parameter_format(yaml_file, fip_regx_dict, "internal", NeutronPortProcessor, "fixed_ips", "subnet")
@validates("R-38236", "R-62802", "R-15287")
def test_external_subnet_format(yaml_file):
- check_ip_format(yaml_file, fip_regx_dict, "external", "fixed_ips", "subnet")
+ check_parameter_format(yaml_file, fip_regx_dict, "external", NeutronPortProcessor, "fixed_ips", "subnet")
@validates("R-84123", "R-76160")
diff --git a/ice_validator/tests/utils/ports.py b/ice_validator/tests/utils/ports.py
index c005e32..afce592 100644
--- a/ice_validator/tests/utils/ports.py
+++ b/ice_validator/tests/utils/ports.py
@@ -36,120 +36,114 @@
# ============LICENSE_END============================================
#
#
-from .network_roles import get_network_role_and_type
-from tests.structures import Heat, NeutronPortProcessor
-from tests.helpers import parameter_type_to_heat_type
+from tests.structures import Heat
+from tests.helpers import parameter_type_to_heat_type, prop_iterator
from . import nested_dict
-def check_ip_format(yaml_file, regx, port_type, resource_property, nested_property):
+def check_parameter_format(yaml_file, regx, intext, resource_processor, *properties):
"""
yaml_file: input file to check
regx: dictionary containing the regex to use to validate parameter
- port_type: internal or external
- resource_property: OS::Neutron::Port property to check for parameter
- nested_property: resource_property will be a list of dicts, this is the key to index into
+ intext: internal or external
+ resource_processor: resource type specific helper, defined in structures.py
+ properties: arg list of property that is being checked
"""
- invalid_ips = []
+
+ invalid_parameters = []
heat = Heat(filepath=yaml_file)
- ports = heat.get_resource_by_type("OS::Neutron::Port")
+ resource_type = resource_processor.resource_type
+ resources = heat.get_resource_by_type(resource_type)
heat_parameters = heat.parameters
-
- for rid, resource in ports.items():
- network_role, network_type = get_network_role_and_type(resource)
- if (
- network_type != port_type
- ): # skipping if port type (internal/external) doesn't match
- continue
-
- name, port_match = NeutronPortProcessor.get_rid_match_tuple(rid)
+ for rid, resource in resources.items():
+ resource_intext, port_match = resource_processor.get_rid_match_tuple(rid)
if not port_match:
continue # port resource ID not formatted correctely
- params = nested_dict.get(resource, "properties", resource_property, default={})
+ if (
+ resource_intext != intext
+ ): # skipping if type (internal/external) doesn't match
+ continue
- for param in params:
- prop = nested_dict.get(param, nested_property)
+ for param in prop_iterator(resource, *properties):
if (
- not prop
- or not isinstance(prop, dict)
- or "get_resource" in prop
- or "get_attr" in prop
- # or "str_replace" in prop - should str_replace be checked?
+ param
+ and isinstance(param, dict)
+ and "get_resource" not in param
+ and "get_attr" not in param
):
- continue # lets only check parameters shall we?
-
- # checking parameter uses get_param
- parameter = nested_dict.get(prop, "get_param")
- if not parameter:
- msg = (
- "Unexpected parameter format for OS::Neutron::Port {} property {}: {}. "
- + "Please consult the heat guidelines documentation for details."
- ).format(rid, resource_property, prop)
- invalid_ips.append(msg) # should this be a failure?
- continue
-
- # getting parameter if the get_param uses list, and getting official HEAT parameter type
- parameter_type = parameter_type_to_heat_type(parameter)
- if parameter_type == "comma_delimited_list":
- parameter = parameter[0]
- elif parameter_type != "string":
- continue
-
- # checking parameter format = type defined in template
- heat_parameter_type = nested_dict.get(heat_parameters, parameter, "type")
- if not heat_parameter_type or heat_parameter_type != parameter_type:
- msg = (
- "OS::Neutron::Port {} parameter {} defined as type {} "
- + "is being used as type {} in the heat template"
- ).format(
- resource_property, parameter, heat_parameter_type, parameter_type
- )
- invalid_ips.append(msg)
- continue
-
- # if parameter type is not in regx dict, then it is not supported by automation
- regx_dict = regx[port_type].get(parameter_type)
- if not regx_dict:
- msg = (
- "WARNING: OS::Neutron::Port {} parameter {} defined as type {} "
- + "is not supported by platform automation. If this VNF is not able "
- + "to adhere to this requirement, please consult the Heat Orchestration "
- + "Template guidelines for alternative solutions. If already adhering to "
- + "an alternative provided by the heat guidelines, please disregard this "
- + "message."
- ).format(resource_property, parameter, parameter_type)
- invalid_ips.append(msg)
- continue
-
- # checking if param adheres to guidelines format
- regexp = regx[port_type][parameter_type]["machine"]
- readable_format = regx[port_type][parameter_type]["readable"]
- match = regexp.match(parameter)
- if not match:
- msg = "{} parameter {} does not follow format {}".format(
- resource_property, parameter, readable_format
- )
- invalid_ips.append(msg)
- continue
-
- # checking that parameter includes correct vm_type/network_role
- parameter_checks = regx.get("parameter_to_resource_comparisons", [])
- for check in parameter_checks:
- resource_match = port_match.group(check)
- if (
- resource_match
- and not parameter.startswith(resource_match)
- and parameter.find("_{}_".format(resource_match)) == -1
- ):
+
+ # checking parameter uses get_param
+ parameter = param.get("get_param")
+ if not parameter:
+ msg = (
+ "Unexpected parameter format for {} {} property {}: {}. "
+ + "Please consult the heat guidelines documentation for details."
+ ).format(resource_type, rid, properties, param)
+ invalid_parameters.append(msg) # should this be a failure?
+ continue
+
+ # getting parameter if the get_param uses list, and getting official HEAT parameter type
+ parameter_type = parameter_type_to_heat_type(parameter)
+ if parameter_type == "comma_delimited_list":
+ parameter = parameter[0]
+ elif parameter_type != "string":
+ continue
+
+ # checking parameter format = parameter type defined in parameters section
+ heat_parameter_type = nested_dict.get(heat_parameters, parameter, "type")
+ if not heat_parameter_type or heat_parameter_type != parameter_type:
msg = (
- "OS::Neutron::Port {0} property {1} parameter "
- + "{2} {3} does match resource {3} {4}"
- ).format(rid, resource_property, parameter, check, resource_match)
- invalid_ips.append(msg)
+ "{} {} parameter {} defined as type {} "
+ + "is being used as type {} in the heat template"
+ ).format(
+ resource_type, properties, parameter, heat_parameter_type, parameter_type
+ )
+ invalid_parameters.append(msg) # should this actually be an error?
+ continue
+
+ # if parameter type is not in regx dict, then it is not supported by automation
+ regx_dict = regx[resource_intext].get(parameter_type)
+ if not regx_dict:
+ msg = (
+ "WARNING: {} {} parameter {} defined as type {} "
+ "is not supported by platform automation. If this VNF is not able "
+ "to adhere to this requirement, please consult the Heat Orchestration "
+ "Template guidelines for alternative solutions. If already adhering to "
+ "an alternative provided by the heat guidelines, please disregard this "
+ "message."
+ ).format(resource_type, properties, parameter, parameter_type)
+ invalid_parameters.append(msg)
+ continue
+
+ # checking if param adheres to guidelines format
+ regexp = regx[resource_intext][parameter_type]["machine"]
+ readable_format = regx[resource_intext][parameter_type]["readable"]
+ match = regexp.match(parameter)
+ if not match:
+ msg = "{} {} property {} parameter {} does not follow {} format {}".format(
+ resource_type, rid, properties, parameter, resource_intext, readable_format
+ )
+ invalid_parameters.append(msg)
continue
- assert not invalid_ips, "%s" % "\n".join(invalid_ips)
+ # checking that parameter includes correct vm_type/network_role
+ parameter_checks = regx.get("parameter_to_resource_comparisons", [])
+ for check in parameter_checks:
+ resource_match = port_match.group(check)
+ if (
+ resource_match
+ and not parameter.startswith(resource_match)
+ and parameter.find("_{}_".format(resource_match)) == -1
+ ):
+ msg = (
+ "{0} {1} property {2} parameter "
+ "{3} {4} does match resource {4} {5}"
+ ).format(resource_type, rid, properties, parameter, check, resource_match)
+ invalid_parameters.append(msg)
+ continue
+
+ assert not invalid_parameters, "%s" % "\n".join(invalid_parameters)
def get_list_of_ports_attached_to_nova_server(nova_server):