diff --git a/vmware_nsx_tempest/lib/__init__.py b/vmware_nsx_tempest/lib/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/vmware_nsx_tempest/tests/nsxv/scenario/test_neutron_resources_heat.py b/vmware_nsx_tempest/lib/heat.py similarity index 65% rename from vmware_nsx_tempest/tests/nsxv/scenario/test_neutron_resources_heat.py rename to vmware_nsx_tempest/lib/heat.py index 76580e39c9..71cfece36e 100644 --- a/vmware_nsx_tempest/tests/nsxv/scenario/test_neutron_resources_heat.py +++ b/vmware_nsx_tempest/lib/heat.py @@ -22,60 +22,71 @@ from oslo_log import log as logging from tempest.api.orchestration import base from tempest.common.utils import data_utils from tempest import config -from tempest.lib import decorators from tempest.scenario import manager -from tempest import test +from vmware_nsx_tempest.services import nsxv3_client from vmware_nsx_tempest.services import nsxv_client - CONF = config.CONF LOG = logging.getLogger(__name__) -DIR_PATH = '/opt/stack/vmware-nsx/vmware_nsx_tempest/tests/' class HeatSmokeTest(base.BaseOrchestrationTest, manager.NetworkScenarioTest): + """ + Deploy and Test Neutron Resources using HEAT. - """Deploy and Test Neutron Resources using HEAT. - - The script load the neutron resources from template and fully - validates successful deployment of all resources from the template. - The template consists of two toplogies with Shared and Exclusive router. - Tests will be common to toplogies (pls refer template for topo info)and - will be as below : - 1. verify created resources from template - 2. verify all created resouces from template - -->neutronDB-->NSXbackend - 3. check same network connectivity - 4. check cross network connectivity """ - def setUp(self): - super(HeatSmokeTest, self).setUp() - self.external_network = CONF.scenario.outside_world_servers + @classmethod + def setup_clients(cls): + super(HeatSmokeTest, cls).setup_clients() + cls.routers_client = cls.os.routers_client + cls.backend = CONF.network.backend + if cls.backend == 'nsxv3': + cls.filename = 'nsxt_neutron_smoke' + cls.nsx = nsxv3_client.NSXV3Client(CONF.nsxv3.nsx_manager, + CONF.nsxv3.nsx_user, + CONF.nsxv3.nsx_password) + elif cls.backend == 'nsxv': + cls.filename = 'nsxv_neutron_smoke' + manager_ip = re.search(r"(\d{1,3}\.){3}\d{1,3}", + CONF.nsxv.manager_uri).group(0) + cls.vsm = nsxv_client.VSMClient( + manager_ip, CONF.nsxv.user, CONF.nsxv.password) + + @classmethod + def setup_credentials(cls): + cls.set_network_resources() + super(HeatSmokeTest, cls).setup_credentials() @classmethod def read_template(cls, name, ext='yaml'): - loc = ["templates", "%s.%s" % (name, ext)] - filepath = os.path.join(DIR_PATH, *loc) + loc = ["tests", "templates", "%s.%s" % (name, ext)] + dir_path = os.path.dirname(__file__).split('/') + dir_path.pop() + dir_path = '/'.join(dir_path) + filepath = os.path.join(dir_path, *loc) if os.path.isfile(filepath): with open(filepath, "r") as f: content = f.read() return content else: - raise IOError("File %s not found " % filepath) + raise IOError @classmethod def load_template(cls, name, ext='yaml'): - loc = ["templates", "%s.%s" % (name, ext)] - filepath = os.path.join(DIR_PATH, *loc) + loc = ["tests", "templates", "%s.%s" % (name, ext)] + dir_path = os.path.dirname(__file__).split('/') + dir_path.pop() + dir_path = '/'.join(dir_path) + filepath = os.path.join(dir_path, *loc) if os.path.isfile(filepath): with open(filepath, "r") as f: return yaml.safe_load(f) else: - raise IOError("File %s not found " % filepath) + raise IOError @classmethod def resource_setup(cls): @@ -83,11 +94,11 @@ class HeatSmokeTest(base.BaseOrchestrationTest, cls.stack_name = data_utils.rand_name('heat') try: cls.neutron_basic_template = cls.load_template( - 'nsxv_neutron_smoke') - template = cls.read_template('nsxv_neutron_smoke') + cls.filename) + template = cls.read_template(cls.filename) except IOError as e: - LOG.exception(("file nsxv_neutron_smoke.yaml not found %(rsp)s") % - {'rsp': e}) + LOG.exception(("file %(rsp)s not found %(rsp1)s") % + {'rsp': cls.filename, 'rsp1': e}) cls.stack_identifier = cls.create_stack(cls.stack_name, template) cls.client.wait_for_stack_status(cls.stack_identifier, 'CREATE_COMPLETE') @@ -98,21 +109,6 @@ class HeatSmokeTest(base.BaseOrchestrationTest, for resource in cls.resources: cls.test_resources[resource['logical_resource_id']] = resource - @classmethod - def setup_credentials(cls): - cls.set_network_resources() - super(HeatSmokeTest, cls).setup_credentials() - - @classmethod - def setup_clients(cls): - super(HeatSmokeTest, cls).setup_clients() - cls.routers_client = cls.os.routers_client - cls.subnets_client = cls.os.subnets_client - manager_ip = re.search(r"(\d{1,3}\.){3}\d{1,3}", - CONF.nsxv.manager_uri).group(0) - cls.vsm = nsxv_client.VSMClient( - manager_ip, CONF.nsxv.user, CONF.nsxv.password) - def _resource_list_check(self, resource): # sorts out the resources and returns resource id if resource == 'networks': @@ -121,7 +117,6 @@ class HeatSmokeTest(base.BaseOrchestrationTest, elif resource == 'routers': body = self.routers_client.list_routers() component = 'OS::Neutron::Router' - print(body) elif resource == 'servers': body = self.servers_client.list_servers() component = 'OS::Nova::Server' @@ -157,9 +152,7 @@ class HeatSmokeTest(base.BaseOrchestrationTest, {'dest': remote_ip, 'src': floating_ip}) raise - @decorators.idempotent_id('f693a425-b018-4cde-96ab-cdd5b858e15c') - @test.attr(type=["smoke"]) - def test_created_resources(self): + def check_created_resources(self): """Verifies created resources from template .""" for resource in self.resources: msg = 'resource %s not create successfully' \ @@ -168,35 +161,40 @@ class HeatSmokeTest(base.BaseOrchestrationTest, msg) self.assertIsInstance(resource, dict) - @decorators.idempotent_id('3c3ccfcb-e50b-4372-82dc-d5b473acd506') - @test.attr(type=["smoke"]) - def test_created_network(self): + def check_created_network(self): """Verifies created neutron networks.""" network_id_list = self._resource_list_check(resource='networks') for network_id in network_id_list: body = self.networks_client.show_network(network_id) - self.assertEqual('True', str(body['network']['admin_state_up'])) + self.assertEqual('True', str(body['network'] + ['admin_state_up'])) msg = 'newtwork %s not found' % body['network']['name'] - self.assertIsNotNone(self.vsm.get_logical_switch(network_id), msg) + if self.backend == 'nsxv3': + self.assertIsNotNone(self.nsx.get_logical_switch( + body['network']['name'], body['network']['id']), msg) + elif self.backend == 'nsxv': + self.assertIsNotNone(self.vsm.get_logical_switch(network_id), + msg) - @decorators.idempotent_id('b3b103a7-69b2-42ea-a1b8-aa11cc551df9') - @test.attr(type=["smoke"]) - def test_created_router(self): + def check_created_router(self): """Verifies created router.""" router_id_list = self._resource_list_check(resource='routers') for router_id in router_id_list: body = self.routers_client.show_router(router_id) self.assertEqual('True', str(body['router']['admin_state_up'])) - if (body['router']['router_type']) != 'shared': - router_edge_name = "%s-%s" % ( - body['router']['name'], body['router']['id']) - exc_edge = self.vsm.get_edge(router_edge_name) - msg = 'exc edge %s not found' % body['router']['name'] - self.assertTrue(exc_edge is not None, msg) + if self.backend == 'nsxv3': + msg = 'router %s not found' % body['router']['name'] + self.assertIsNotNone(self.nsx.get_logical_router( + body['router']['name'], body['router']['id']), msg) + elif self.backend == 'nsxv': + if (body['router']['router_type']) != 'shared': + router_edge_name = "%s-%s" % ( + body['router']['name'], body['router']['id']) + exc_edge = self.vsm.get_edge(router_edge_name) + msg = 'exc edge %s not found' % body['router']['name'] + self.assertTrue(exc_edge is not None, msg) - @decorators.idempotent_id('2b29dfef-6d9f-4a70-9377-af432100ef10') - @test.attr(type=["smoke"]) - def test_created_server(self): + def check_created_server(self): """Verifies created sever.""" server_id_list = self._resource_list_check(resource='servers') for server_id in server_id_list: @@ -204,24 +202,20 @@ class HeatSmokeTest(base.BaseOrchestrationTest, msg = 'server %s not active ' % (server) self.assertEqual('ACTIVE', str(server['status']), msg) - @decorators.idempotent_id('d937a607-aa5e-4cf1-bbf9-00044cbe7190') - @test.attr(type=["smoke"]) - def test_topo1_same_network_connectivity_(self): + def check_topo1_same_network_connectivity(self): """Verifies same network connnectivity for Topology 1 """ address_list = [] - topo1_server1_floatingip = self.get_stack_output(self.stack_identifier, - 'topo1_server1_floatingip') - server4_private_ip = self.get_stack_output(self.stack_identifier, - 'topo1_server4_private_ip') + topo1_server1_floatingip = self.get_stack_output( + self.stack_identifier, 'topo1_server1_floatingip') + server4_private_ip = self.get_stack_output( + self.stack_identifier, 'topo1_server4_private_ip') address_list.append(server4_private_ip) - LOG.info((" floating ip :%(rsp)s and private ip list : %(rsp1)s") % + LOG.info(" floating ip :%(rsp)s and private ip list : %(rsp1)s" % {"rsp": topo1_server1_floatingip, "rsp1": address_list}) self._check_server_connectivity(topo1_server1_floatingip, address_list, should_connect=True) - @decorators.idempotent_id('fdbc8b1a-755a-4b37-93e7-0a268e422f05') - @test.attr(type=["smoke"]) - def test_topo1_cross_network_connectivity(self): + def check_topo1_cross_network_connectivity(self): """Verifies cross network connnectivity for Topology 1 """ address_list = [] topo1_server1_floatingip = self.get_stack_output( @@ -232,21 +226,19 @@ class HeatSmokeTest(base.BaseOrchestrationTest, 'topo1_server3_private_ip') address_list.append(server2_private_ip) address_list.append(server3_private_ip) - LOG.info(("floating ip :%(rsp)s and private ip list : %(rsp1)s") % + LOG.info("floating ip :%(rsp)s and private ip list : %(rsp1)s" % {"rsp": topo1_server1_floatingip, "rsp1": address_list}) self._check_server_connectivity(topo1_server1_floatingip, address_list, should_connect=True) - @decorators.idempotent_id('bcefd117-c55e-499d-a34b-653b8981f1c5') - @test.attr(type=["smoke"]) - def test_topo1_cross_external_connectivity(self): + def check_topo1_external_connectivity(self): """Verifies external network connnectivity for Topology 1 """ address_list = [] - topo1_server1_floatingip = self.get_stack_output(self.stack_identifier, - 'topo1_server1_floatingip') + topo1_server1_floatingip = self.get_stack_output( + self.stack_identifier, 'topo1_server1_floatingip') external_network = self.external_network[0] address_list.append(external_network) - LOG.info(("floating ip :%(rsp)s and external ip : %(rsp1)s") % + LOG.info("floating ip :%(rsp)s and external ip : %(rsp1)s" % {"rsp": topo1_server1_floatingip, "rsp1": address_list}) - self._check_server_connectivity(topo1_server1_floatingip, address_list, - should_connect=True) + self._check_server_connectivity(topo1_server1_floatingip, + address_list, should_connect=True) diff --git a/vmware_nsx_tempest/tests/nsxv/scenario/test_neutron_resources_heat_nsxv.py b/vmware_nsx_tempest/tests/nsxv/scenario/test_neutron_resources_heat_nsxv.py new file mode 100644 index 0000000000..d3239aadf2 --- /dev/null +++ b/vmware_nsx_tempest/tests/nsxv/scenario/test_neutron_resources_heat_nsxv.py @@ -0,0 +1,58 @@ +# Copyright 2017 VMware Inc +# All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file 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. + +from tempest.lib import decorators + +from vmware_nsx_tempest.lib import heat + + +class HeatTest(heat.HeatSmokeTest): + """ + Deploy and Test Neutron Resources using HEAT. + + The script loads the neutron resources from template and fully + validates successful deployment of all resources from the template. + + """ + + @decorators.idempotent_id('fcc70627-dee0-466a-a59c-ae844a7ec59d') + def test_topo1_created_resources(self): + """Verifies created resources from template .""" + self.check_created_resources() + + @decorators.idempotent_id('ed1e9058-88b6-417e-bfa1-12531fa16cd0') + def test_topo1_created_network(self): + """Verifies created neutron networks.""" + self.check_created_network() + + @decorators.idempotent_id('58a1f904-18c6-43b3-8d7b-c1246b65ac1b') + def test_topo1_created_router(self): + """Verifies created router.""" + self.check_created_router() + + @decorators.idempotent_id('dece79ae-03e8-4d77-9484-5552a1f23412') + def test_topo1_created_server(self): + """Verifies created sever.""" + self.check_created_server() + + @decorators.idempotent_id('6e6cc35c-d58c-490c-ad88-f085c260bc73') + def test_topo1_same_network(self): + """Verifies same network connnectivity for Topology 1 """ + self.check_topo1_same_network_connectivity() + + @decorators.idempotent_id('1ae85f38-c78a-43ca-9b39-278131907681') + def test_topo1_cross_network(self): + """Verifies cross network connnectivity for Topology 1 """ + self.check_topo1_cross_network_connectivity() diff --git a/vmware_nsx_tempest/tests/nsxv3/scenario/test_neutron_resources_heat_nsxt.py b/vmware_nsx_tempest/tests/nsxv3/scenario/test_neutron_resources_heat_nsxt.py new file mode 100644 index 0000000000..43bb94dc5b --- /dev/null +++ b/vmware_nsx_tempest/tests/nsxv3/scenario/test_neutron_resources_heat_nsxt.py @@ -0,0 +1,58 @@ +# Copyright 2017 VMware Inc +# All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file 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. + +from tempest.lib import decorators + +from vmware_nsx_tempest.lib import heat + + +class HeatTest(heat.HeatSmokeTest): + """ + Deploy and Test Neutron Resources using HEAT. + + The script loads the neutron resources from template and fully + validates successful deployment of all resources from the template. + + """ + + @decorators.idempotent_id('cb772c73-5948-4bd3-91d1-d85af2577362') + def test_topo1_created_resources(self): + """Verifies created resources from template .""" + self.check_created_resources() + + @decorators.idempotent_id('4f4cb71e-404f-4810-8898-5d6d70650016') + def test_topo1_created_network(self): + """Verifies created neutron networks.""" + self.check_created_network() + + @decorators.idempotent_id('7e6452de-62c1-4daf-a031-013889b1d4ba') + def test_topo1_created_router(self): + """Verifies created router.""" + self.check_created_router() + + @decorators.idempotent_id('24a3c0f8-3482-47fe-8c80-561a264a66d0') + def test_topo1_created_server(self): + """Verifies created sever.""" + self.check_created_server() + + @decorators.idempotent_id('1fc3b998-d730-4f90-8ad2-bc4f2eeb7157') + def test_topo1_same_network(self): + """Verifies same network connnectivity for Topology 1 """ + self.check_topo1_same_network_connectivity() + + @decorators.idempotent_id('aec9b109-2501-41de-9a24-444ced8b2668') + def test_topo1_cross_network(self): + """Verifies cross network connnectivity for Topology 1 """ + self.check_topo1_cross_network_connectivity() diff --git a/vmware_nsx_tempest/tests/templates/nsxt_neutron_smoke.yaml b/vmware_nsx_tempest/tests/templates/nsxt_neutron_smoke.yaml new file mode 100644 index 0000000000..6d247f78f8 --- /dev/null +++ b/vmware_nsx_tempest/tests/templates/nsxt_neutron_smoke.yaml @@ -0,0 +1,203 @@ +heat_template_version: 2013-05-23 + +description: > + Topology 1: + - 4 servers (Cirros)) + - 2 Logical Switches + - 1 Logical Router (Shared) + - 2 Security Group allowing HTTP + +parameters: + + public_net: + label: Public Network ID for external connectivity + type: string + description: > + ID or name of public network + # Need to update this network UUID for each vPod. + default: public + cirros_image: + default: cirros-0.3.3-x86_64-ESX + description: "cirros image" + type: string + + +resources: + +# Topology1 + + heat_NAT_web_net: + type: OS::Neutron::Net + properties: + name: heat_NAT_web + + heat_NAT_web_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: heat_NAT_web_net } + cidr: 10.21.1.0/24 + dns_nameservers: [ "10.166.17.90" ] + + heat_NAT_db_net: + type: OS::Neutron::Net + properties: + name: heat_NAT_db + + heat_NAT_db_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: heat_NAT_db_net } + cidr: 10.21.2.0/24 + dns_nameservers: [ "10.166.17.90" ] + + my_key: + type: OS::Nova::KeyPair + properties: + save_private_key: true + name: my_key + + router: + type: OS::Neutron::Router + properties: + admin_state_up: true + name: heat_NAT_router + + router_gw: + type: OS::Neutron::RouterGateway + properties: + network_id: { get_param: public_net} + router_id: { get_resource: router } + + router_interface1: + type: OS::Neutron::RouterInterface + properties: + router_id: { get_resource: router } + subnet_id: { get_resource: heat_NAT_web_subnet } + + router_interface2: + type: OS::Neutron::RouterInterface + properties: + router_id: { get_resource: router } + subnet_id: { get_resource: heat_NAT_db_subnet } + + + heat_NAT_web_secgroup: + type: OS::Neutron::SecurityGroup + properties: + name: heat_NAT_web_secgroup + rules: + - protocol: tcp + remote_ip_prefix: 0.0.0.0/0 + port_range_min: 443 + port_range_max: 443 + - protocol: tcp + remote_ip_prefix: 0.0.0.0/0 + port_range_min: 22 + port_range_max: 22 + - protocol: icmp + remote_ip_prefix: 0.0.0.0/0 + + heat_NAT_db_secgroup: + type: OS::Neutron::SecurityGroup + properties: + name: heat_NAT_db_secgroup + rules: + - protocol: tcp + remote_mode: remote_group_id + remote_group_id: { get_resource: heat_NAT_web_secgroup } + port_range_min: 3307 + port_range_max: 3307 + - protocol: icmp + remote_ip_prefix: 0.0.0.0/0 + + server1_port: + type: OS::Neutron::Port + properties: + network_id: { get_resource: heat_NAT_web_net } + security_groups: + - { get_resource: heat_NAT_web_secgroup } + + server1_instance: + type: OS::Nova::Server + properties: + image: { get_param: cirros_image} + flavor: m1.tiny + key_name: { get_resource: my_key } + networks: + - port: { get_resource: server1_port } + + server1_floating_ip: + type: OS::Neutron::FloatingIP + properties: + floating_network_id: { get_param: public_net } + port_id: { get_resource: server1_port } + + + server2_port: + type: OS::Neutron::Port + properties: + network_id: { get_resource: heat_NAT_db_net } + security_groups: + - { get_resource: heat_NAT_db_secgroup } + + server2_instance: + type: OS::Nova::Server + properties: + image: { get_param: cirros_image} + flavor: m1.tiny + key_name: { get_resource: my_key } + networks: + - port: { get_resource: server2_port } + + server3_port: + type: OS::Neutron::Port + properties: + network_id: { get_resource: heat_NAT_db_net } + security_groups: + - { get_resource: heat_NAT_db_secgroup } + + + server3_instance: + type: OS::Nova::Server + properties: + image: { get_param: cirros_image} + flavor: m1.tiny + key_name: { get_resource: my_key } + networks: + - port: { get_resource: server3_port } + + server4_port: + type: OS::Neutron::Port + properties: + network_id: { get_resource: heat_NAT_web_net } + security_groups: + - { get_resource: heat_NAT_web_secgroup } + + server4_instance: + type: OS::Nova::Server + properties: + image: { get_param: cirros_image} + flavor: m1.tiny + key_name: { get_resource: my_key } + networks: + - port: { get_resource: server4_port } + +outputs: + topo1_server1_floatingip: + description: Floating IP address of Topology1_Server1_floatingip + value: { get_attr: [ server1_floating_ip, floating_ip_address ] } + topo1_server1_private_ip: + description: Private IP address of the deployed compute instance + value: { get_attr: [server1_instance, networks, heat_NAT_web, 0] } + topo1_server2_private_ip: + description: Private IP address of the deployed compute instance + value: { get_attr: [server2_instance, networks, heat_NAT_db, 0] } + topo1_server3_private_ip: + description: Private IP address of the deployed compute instance + value: { get_attr: [server3_instance, networks, heat_NAT_db, 0] } + topo1_server4_private_ip: + description: Private IP address of the deployed compute instance + value: { get_attr: [server4_instance, networks, heat_NAT_web, 0] } + private_key: + description: Private key + value: { get_attr: [ my_key, private_key ] }