VPNaas vpnservice test cases
Adding testcases for vpn service create, list, delete, and show
part of blueprint: vpnaas-api-test-cases
Change-Id: I015fd503a198f93bfc7382e30b2aff5c74b3fd30
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index c3a66c5..b6c2679 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -20,8 +20,11 @@
from tempest import clients
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
+from tempest.openstack.common import log as logging
import tempest.test
+LOG = logging.getLogger(__name__)
+
class BaseNetworkTest(tempest.test.BaseTestCase):
@@ -61,26 +64,79 @@
cls.vips = []
cls.members = []
cls.health_monitors = []
+ cls.vpnservices = []
@classmethod
def tearDownClass(cls):
- for health_monitor in cls.health_monitors:
- cls.client.delete_health_monitor(health_monitor['id'])
- for member in cls.members:
- cls.client.delete_member(member['id'])
- for vip in cls.vips:
- cls.client.delete_vip(vip['id'])
- for pool in cls.pools:
- cls.client.delete_pool(pool['id'])
- for port in cls.ports:
- cls.client.delete_port(port['id'])
+ has_exception = False
+ for vpnservice in cls.vpnservices:
+ try:
+ cls.client.delete_vpn_service(vpnservice['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
+
for router in cls.routers:
- cls.client.delete_router(router['id'])
+ try:
+ resp, body = cls.client.list_router_interfaces(router['id'])
+ interfaces = body['ports']
+ for i in interfaces:
+ cls.client.remove_router_interface_with_subnet_id(
+ router['id'], i['fixed_ips'][0]['subnet_id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
+ try:
+ cls.client.delete_router(router['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
+
+ for health_monitor in cls.health_monitors:
+ try:
+ cls.client.delete_health_monitor(health_monitor['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
+ for member in cls.members:
+ try:
+ cls.client.delete_member(member['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
+ for vip in cls.vips:
+ try:
+ cls.client.delete_vip(vip['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
+ for pool in cls.pools:
+ try:
+ cls.client.delete_pool(pool['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
+ for port in cls.ports:
+ try:
+ cls.client.delete_port(port['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
for subnet in cls.subnets:
- cls.client.delete_subnet(subnet['id'])
+ try:
+ cls.client.delete_subnet(subnet['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
for network in cls.networks:
- cls.client.delete_network(network['id'])
+ try:
+ cls.client.delete_network(network['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
super(BaseNetworkTest, cls).tearDownClass()
+ if has_exception:
+ raise exceptions.TearDownException()
@classmethod
def create_network(cls, network_name=None):
@@ -179,3 +235,19 @@
health_monitor = body['health_monitor']
cls.health_monitors.append(health_monitor)
return health_monitor
+
+ @classmethod
+ def create_router_interface(cls, router_id, subnet_id):
+ """Wrapper utility that returns a router interface."""
+ resp, interface = cls.client.add_router_interface_with_subnet_id(
+ router_id, subnet_id)
+
+ @classmethod
+ def create_vpnservice(cls, subnet_id, router_id):
+ """Wrapper utility that returns a test vpn service."""
+ resp, body = cls.client.create_vpn_service(
+ subnet_id, router_id, admin_state_up=True,
+ name=rand_name("vpnservice-"))
+ vpnservice = body['vpnservice']
+ cls.vpnservices.append(vpnservice)
+ return vpnservice
diff --git a/tempest/api/network/test_vpnaas_extensions.py b/tempest/api/network/test_vpnaas_extensions.py
new file mode 100644
index 0000000..7a8128b
--- /dev/null
+++ b/tempest/api/network/test_vpnaas_extensions.py
@@ -0,0 +1,96 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack Foundation
+# 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.api.network import base
+from tempest.common.utils.data_utils import rand_name
+from tempest.test import attr
+
+
+class VPNaaSJSON(base.BaseNetworkTest):
+ _interface = 'json'
+
+ """
+ Tests the following operations in the Neutron API using the REST client for
+ Neutron:
+
+ List VPN Services
+ Show VPN Services
+ Create VPN Services
+ Update VPN Services
+ Delete VPN Services
+ """
+
+ @classmethod
+ def setUpClass(cls):
+ super(VPNaaSJSON, cls).setUpClass()
+ cls.network = cls.create_network()
+ cls.subnet = cls.create_subnet(cls.network)
+ cls.router = cls.create_router(rand_name("router-"))
+ cls.create_router_interface(cls.router['id'], cls.subnet['id'])
+ cls.vpnservice = cls.create_vpnservice(cls.subnet['id'],
+ cls.router['id'])
+
+ @attr(type='smoke')
+ def test_list_vpn_services(self):
+ # Verify the VPN service exists in the list of all VPN services
+ resp, body = self.client.list_vpn_services()
+ self.assertEqual('200', resp['status'])
+ vpnservices = body['vpnservices']
+ self.assertIn(self.vpnservice['id'], [v['id'] for v in vpnservices])
+
+ @attr(type='smoke')
+ def test_create_update_delete_vpn_service(self):
+ # Creates a VPN service
+ name = rand_name('vpn-service-')
+ resp, body = self.client.create_vpn_service(self.subnet['id'],
+ self.router['id'],
+ name=name,
+ admin_state_up=True)
+ self.assertEqual('201', resp['status'])
+ vpnservice = body['vpnservice']
+ # Assert if created vpnservices are not found in vpnservices list
+ resp, body = self.client.list_vpn_services()
+ vpn_services = [vs['id'] for vs in body['vpnservices']]
+ self.assertIsNotNone(vpnservice['id'])
+ self.assertIn(vpnservice['id'], vpn_services)
+
+ # TODO(raies): implement logic to update vpnservice
+ # VPNaaS client function to update is implemented.
+ # But precondition is that current state of vpnservice
+ # should be "ACTIVE" not "PENDING*"
+
+ # Verification of vpn service delete
+ resp, body = self.client.delete_vpn_service(vpnservice['id'])
+ self.assertEqual('204', resp['status'])
+ # Asserting if vpn service is found in the list after deletion
+ resp, body = self.client.list_vpn_services()
+ vpn_services = [vs['id'] for vs in body['vpnservices']]
+ self.assertNotIn(vpnservice['id'], vpn_services)
+
+ @attr(type='smoke')
+ def test_show_vpn_service(self):
+ # Verifies the details of a vpn service
+ resp, body = self.client.show_vpn_service(self.vpnservice['id'])
+ self.assertEqual('200', resp['status'])
+ vpnservice = body['vpnservice']
+ self.assertEqual(self.vpnservice['id'], vpnservice['id'])
+ self.assertEqual(self.vpnservice['name'], vpnservice['name'])
+ self.assertEqual(self.vpnservice['description'],
+ vpnservice['description'])
+ self.assertEqual(self.vpnservice['router_id'], vpnservice['router_id'])
+ self.assertEqual(self.vpnservice['subnet_id'], vpnservice['subnet_id'])
+ self.assertEqual(self.vpnservice['tenant_id'], vpnservice['tenant_id'])
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 4b87b91..92c1faf 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -600,3 +600,53 @@
resp, body = self.get(uri, headers=self.headers)
body = json.loads(body)
return resp, body
+
+ def list_vpn_services(self):
+ uri = '%s/vpn/vpnservices' % (self.uri_prefix)
+ resp, body = self.get(uri, self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def create_vpn_service(self, subnet_id, router_id, **kwargs):
+ post_body = {
+ "vpnservice": {
+ "subnet_id": subnet_id,
+ "router_id": router_id
+ }
+ }
+ for key, val in kwargs.items():
+ post_body['vpnservice'][key] = val
+ body = json.dumps(post_body)
+ uri = '%s/vpn/vpnservices' % (self.uri_prefix)
+ resp, body = self.post(uri, headers=self.headers, body=body)
+ body = json.loads(body)
+ return resp, body
+
+ def show_vpn_service(self, uuid):
+ uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
+ resp, body = self.get(uri, self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def delete_vpn_service(self, uuid):
+ uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
+ resp, body = self.delete(uri, self.headers)
+ return resp, body
+
+ def update_vpn_service(self, uuid, description):
+ put_body = {
+ "vpnservice": {
+ "description": description
+ }
+ }
+ body = json.dumps(put_body)
+ uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
+ resp, body = self.put(uri, body=body, headers=self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def list_router_interfaces(self, uuid):
+ uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
+ resp, body = self.get(uri, self.headers)
+ body = json.loads(body)
+ return resp, body
diff --git a/tempest/services/network/xml/network_client.py b/tempest/services/network/xml/network_client.py
index cf8154a..04ad86f 100755
--- a/tempest/services/network/xml/network_client.py
+++ b/tempest/services/network/xml/network_client.py
@@ -547,6 +547,13 @@
body = _root_tag_fetcher_and_xml_to_json_parse(body)
return resp, body
+ def list_router_interfaces(self, uuid):
+ uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
+ resp, body = self.get(uri, self.headers)
+ ports = self._parse_array(etree.fromstring(body))
+ ports = {"ports": ports}
+ return resp, ports
+
def _root_tag_fetcher_and_xml_to_json_parse(xml_returned_body):
body = ET.fromstring(xml_returned_body)