Merge "Added 3 Routers related testcases for Neutron API"
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
new file mode 100644
index 0000000..df85682
--- /dev/null
+++ b/tempest/api/network/test_routers.py
@@ -0,0 +1,133 @@
+# 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 RoutersTest(base.BaseNetworkTest):
+
+ @classmethod
+ def setUpClass(cls):
+ super(RoutersTest, cls).setUpClass()
+
+ def _delete_router(self, router_id):
+ resp, _ = self.client.delete_router(router_id)
+ self.assertEqual(204, resp.status)
+ # Asserting that the router is not found in the list
+ # after deletion
+ resp, list_body = self.client.list_routers()
+ self.assertEqual('200', resp['status'])
+ routers_list = list()
+ for router in list_body['routers']:
+ routers_list.append(router['id'])
+ self.assertNotIn(router_id, routers_list)
+
+ def _remove_router_interface_with_subnet_id(self, router_id, subnet_id):
+ resp, _ = self.client.remove_router_interface_with_subnet_id(
+ router_id, subnet_id)
+ self.assertEqual('200', resp['status'])
+
+ def _remove_router_interface_with_port_id(self, router_id, port_id):
+ resp, _ = self.client.remove_router_interface_with_port_id(
+ router_id, port_id)
+ self.assertEqual('200', resp['status'])
+
+ @attr(type='gate')
+ def test_create_show_list_update_delete_router(self):
+ # Create a router
+ name = rand_name('router-')
+ resp, create_body = self.client.create_router(
+ name, external_gateway_info={
+ "network_id": self.network_cfg.public_network_id},
+ admin_state_up=False)
+ self.assertEqual('201', resp['status'])
+ self.addCleanup(self._delete_router, create_body['router']['id'])
+ self.assertEqual(create_body['router']['name'], name)
+ self.assertEqual(
+ create_body['router']['external_gateway_info']['network_id'],
+ self.network_cfg.public_network_id)
+ self.assertEqual(create_body['router']['admin_state_up'], False)
+ # Show details of the created router
+ resp, show_body = self.client.show_router(
+ create_body['router']['id'])
+ self.assertEqual('200', resp['status'])
+ self.assertEqual(show_body['router']['name'], name)
+ self.assertEqual(
+ show_body['router']['external_gateway_info']['network_id'],
+ self.network_cfg.public_network_id)
+ self.assertEqual(show_body['router']['admin_state_up'], False)
+ # List routers and verify if created router is there in response
+ resp, list_body = self.client.list_routers()
+ self.assertEqual('200', resp['status'])
+ routers_list = list()
+ for router in list_body['routers']:
+ routers_list.append(router['id'])
+ self.assertIn(create_body['router']['id'], routers_list)
+ # Update the name of router and verify if it is updated
+ updated_name = 'updated ' + name
+ resp, update_body = self.client.update_router(
+ create_body['router']['id'], name=updated_name)
+ self.assertEqual('200', resp['status'])
+ self.assertEqual(update_body['router']['name'], updated_name)
+ resp, show_body = self.client.show_router(
+ create_body['router']['id'])
+ self.assertEqual(show_body['router']['name'], updated_name)
+
+ @attr(type='gate')
+ def test_add_remove_router_interface_with_subnet_id(self):
+ network = self.create_network()
+ subnet = self.create_subnet(network)
+ name = rand_name('router-')
+ resp, create_body = self.client.create_router(name)
+ self.addCleanup(self.client.delete_router, create_body['router']['id'])
+ # Add router interafce with subnet id
+ resp, interface = self.client.add_router_interface_with_subnet_id(
+ create_body['router']['id'], subnet['id'])
+ self.assertEqual('200', resp['status'])
+ self.addCleanup(self._remove_router_interface_with_subnet_id,
+ create_body['router']['id'], subnet['id'])
+ self.assertTrue('subnet_id' in interface.keys())
+ self.assertTrue('port_id' in interface.keys())
+ # Verify router id is equal to device id in port details
+ resp, show_port_body = self.client.show_port(
+ interface['port_id'])
+ self.assertEqual(show_port_body['port']['device_id'],
+ create_body['router']['id'])
+
+ @attr(type='gate')
+ def test_add_remove_router_interface_with_port_id(self):
+ network = self.create_network()
+ self.create_subnet(network)
+ name = rand_name('router-')
+ resp, create_body = self.client.create_router(name)
+ self.addCleanup(self.client.delete_router, create_body['router']['id'])
+ resp, port_body = self.client.create_port(network['id'])
+ # add router interface to port created above
+ resp, interface = self.client.add_router_interface_with_port_id(
+ create_body['router']['id'], port_body['port']['id'])
+ self.assertEqual('200', resp['status'])
+ self.addCleanup(self._remove_router_interface_with_port_id,
+ create_body['router']['id'], port_body['port']['id'])
+ self.assertTrue('subnet_id' in interface.keys())
+ self.assertTrue('port_id' in interface.keys())
+ # Verify router id is equal to device id in port details
+ resp, show_port_body = self.client.show_port(
+ interface['port_id'])
+ self.assertEqual(show_port_body['port']['device_id'],
+ create_body['router']['id'])
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 2c808a9..43b7db2 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -23,8 +23,10 @@
Tempest REST client for Neutron. Uses v2 of the Neutron API, since the
V1 API has been removed from the code base.
- Implements create, delete, list and show for the basic Neutron
- abstractions (networks, sub-networks and ports):
+ Implements create, delete, update, list and show for the basic Neutron
+ abstractions (networks, sub-networks, routers and ports):
+
+ Implements add/remove interface to router using subnet ID / port ID
It also implements list, show, update and reset for OpenStack Networking
quotas
@@ -187,3 +189,89 @@
resp, body = self.put(uri, body=body, headers=self.headers)
body = json.loads(body)
return resp, body
+
+ def list_routers(self):
+ uri = '%s/routers' % (self.uri_prefix)
+ resp, body = self.get(uri, self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def create_router(self, name, **kwargs):
+ post_body = {
+ 'router': {
+ 'name': name,
+ }
+ }
+ post_body['router']['admin_state_up'] = kwargs.get(
+ 'admin_state_up', True)
+ post_body['router']['external_gateway_info'] = kwargs.get(
+ 'external_gateway_info', None)
+ body = json.dumps(post_body)
+ uri = '%s/routers' % (self.uri_prefix)
+ resp, body = self.post(uri, headers=self.headers, body=body)
+ body = json.loads(body)
+ return resp, body
+
+ def delete_router(self, router_id):
+ uri = '%s/routers/%s' % (self.uri_prefix, router_id)
+ resp, body = self.delete(uri, self.headers)
+ return resp, body
+
+ def show_router(self, router_id):
+ uri = '%s/routers/%s' % (self.uri_prefix, router_id)
+ resp, body = self.get(uri, self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def update_router(self, router_id, **kwargs):
+ uri = '%s/routers/%s' % (self.uri_prefix, router_id)
+ resp, body = self.get(uri, self.headers)
+ body = json.loads(body)
+ update_body = {}
+ update_body['name'] = kwargs.get('name', body['router']['name'])
+ update_body['admin_state_up'] = kwargs.get(
+ 'admin_state_up', body['router']['admin_state_up'])
+ # Must uncomment/modify these lines once LP question#233187 is solved
+ #update_body['external_gateway_info'] = kwargs.get(
+ # 'external_gateway_info', body['router']['external_gateway_info'])
+ update_body = dict(router=update_body)
+ update_body = json.dumps(update_body)
+ resp, body = self.put(uri, update_body, self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def add_router_interface_with_subnet_id(self, router_id, subnet_id):
+ uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
+ router_id)
+ update_body = {"subnet_id": subnet_id}
+ update_body = json.dumps(update_body)
+ resp, body = self.put(uri, update_body, self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def add_router_interface_with_port_id(self, router_id, port_id):
+ uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
+ router_id)
+ update_body = {"port_id": port_id}
+ update_body = json.dumps(update_body)
+ resp, body = self.put(uri, update_body, self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def remove_router_interface_with_subnet_id(self, router_id, subnet_id):
+ uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
+ router_id)
+ update_body = {"subnet_id": subnet_id}
+ update_body = json.dumps(update_body)
+ resp, body = self.put(uri, update_body, self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def remove_router_interface_with_port_id(self, router_id, port_id):
+ uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
+ router_id)
+ update_body = {"port_id": port_id}
+ update_body = json.dumps(update_body)
+ resp, body = self.put(uri, update_body, self.headers)
+ body = json.loads(body)
+ return resp, body