Adding network api xml support
Network API tests with xml formatted request body were missing. I added code to support this feature. In the test cases "test_list_subnets" and "test_list_networks", response code check was also missing. I also added this check in the code. Change-Id: I876c720b93e0d0cded96de0549edd6115fa1c655
This commit is contained in:
@@ -48,7 +48,7 @@ class BaseNetworkTest(tempest.test.BaseTestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(BaseNetworkTest, cls).setUpClass()
|
||||
os = clients.Manager()
|
||||
os = clients.Manager(interface=cls._interface)
|
||||
cls.network_cfg = os.config.network
|
||||
if not cls.config.service_available.neutron:
|
||||
raise cls.skipException("Neutron support is required")
|
||||
|
||||
@@ -23,7 +23,8 @@ from tempest import exceptions
|
||||
from tempest.test import attr
|
||||
|
||||
|
||||
class NetworksTest(base.BaseNetworkTest):
|
||||
class NetworksTestJSON(base.BaseNetworkTest):
|
||||
_interface = 'json'
|
||||
|
||||
"""
|
||||
Tests the following operations in the Neutron API using the REST client for
|
||||
@@ -55,7 +56,7 @@ class NetworksTest(base.BaseNetworkTest):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(NetworksTest, cls).setUpClass()
|
||||
super(NetworksTestJSON, cls).setUpClass()
|
||||
cls.network = cls.create_network()
|
||||
cls.name = cls.network['name']
|
||||
cls.subnet = cls.create_subnet(cls.network)
|
||||
@@ -109,7 +110,7 @@ class NetworksTest(base.BaseNetworkTest):
|
||||
self.assertEqual('200', resp['status'])
|
||||
updated_subnet = body['subnet']
|
||||
self.assertEqual(updated_subnet['name'], new_subnet)
|
||||
# Deletes subnet and network
|
||||
# Delete subnet and network
|
||||
resp, body = self.client.delete_subnet(subnet_id)
|
||||
self.assertEqual('204', resp['status'])
|
||||
resp, body = self.client.delete_network(net_id)
|
||||
@@ -128,6 +129,7 @@ class NetworksTest(base.BaseNetworkTest):
|
||||
def test_list_networks(self):
|
||||
# Verify the network exists in the list of all networks
|
||||
resp, body = self.client.list_networks()
|
||||
self.assertEqual('200', resp['status'])
|
||||
networks = body['networks']
|
||||
found = None
|
||||
for n in networks:
|
||||
@@ -149,6 +151,7 @@ class NetworksTest(base.BaseNetworkTest):
|
||||
def test_list_subnets(self):
|
||||
# Verify the subnet exists in the list of all subnets
|
||||
resp, body = self.client.list_subnets()
|
||||
self.assertEqual('200', resp['status'])
|
||||
subnets = body['subnets']
|
||||
found = None
|
||||
for n in subnets:
|
||||
@@ -159,7 +162,7 @@ class NetworksTest(base.BaseNetworkTest):
|
||||
|
||||
@attr(type='gate')
|
||||
def test_create_update_delete_port(self):
|
||||
# Verify that successful port creation & deletion
|
||||
# Verify that successful port creation, update & deletion
|
||||
resp, body = self.client.create_port(self.network['id'])
|
||||
self.assertEqual('201', resp['status'])
|
||||
port = body['port']
|
||||
@@ -174,7 +177,7 @@ class NetworksTest(base.BaseNetworkTest):
|
||||
self.assertEqual('204', resp['status'])
|
||||
|
||||
@attr(type='gate')
|
||||
def test_show_ports(self):
|
||||
def test_show_port(self):
|
||||
# Verify the details of port
|
||||
resp, body = self.client.show_port(self.port['id'])
|
||||
self.assertEqual('200', resp['status'])
|
||||
@@ -221,3 +224,7 @@ class NetworksTest(base.BaseNetworkTest):
|
||||
for n in created_networks:
|
||||
self.assertIsNotNone(n['id'])
|
||||
self.assertIn(n['id'], networks_list)
|
||||
|
||||
|
||||
class NetworksTestXML(NetworksTestJSON):
|
||||
_interface = 'xml'
|
||||
|
||||
@@ -23,6 +23,7 @@ from tempest.test import attr
|
||||
|
||||
|
||||
class QuotasTest(base.BaseNetworkTest):
|
||||
_interface = 'json'
|
||||
|
||||
"""
|
||||
Tests the following operations in the Neutron API using the REST client for
|
||||
|
||||
@@ -21,6 +21,7 @@ from tempest.test import attr
|
||||
|
||||
|
||||
class RoutersTest(base.BaseNetworkTest):
|
||||
_interface = 'json'
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
||||
@@ -90,7 +90,8 @@ from tempest.services.identity.xml.identity_client import IdentityClientXML
|
||||
from tempest.services.identity.xml.identity_client import TokenClientXML
|
||||
from tempest.services.image.v1.json.image_client import ImageClientJSON
|
||||
from tempest.services.image.v2.json.image_client import ImageClientV2JSON
|
||||
from tempest.services.network.json.network_client import NetworkClient
|
||||
from tempest.services.network.json.network_client import NetworkClientJSON
|
||||
from tempest.services.network.xml.network_client import NetworkClientXML
|
||||
from tempest.services.object_storage.account_client import AccountClient
|
||||
from tempest.services.object_storage.account_client import \
|
||||
AccountClientCustomizedHeader
|
||||
@@ -116,6 +117,11 @@ IMAGES_CLIENTS = {
|
||||
"xml": ImagesClientXML,
|
||||
}
|
||||
|
||||
NETWORKS_CLIENTS = {
|
||||
"json": NetworkClientJSON,
|
||||
"xml": NetworkClientXML,
|
||||
}
|
||||
|
||||
KEYPAIRS_CLIENTS = {
|
||||
"json": KeyPairsClientJSON,
|
||||
"xml": KeyPairsClientXML,
|
||||
@@ -295,6 +301,7 @@ class Manager(object):
|
||||
|
||||
try:
|
||||
self.servers_client = SERVERS_CLIENTS[interface](*client_args)
|
||||
self.network_client = NETWORKS_CLIENTS[interface](*client_args)
|
||||
self.limits_client = LIMITS_CLIENTS[interface](*client_args)
|
||||
if self.config.service_available.glance:
|
||||
self.images_client = IMAGES_CLIENTS[interface](*client_args)
|
||||
@@ -339,7 +346,6 @@ class Manager(object):
|
||||
except KeyError:
|
||||
msg = "Unsupported interface type `%s'" % interface
|
||||
raise exceptions.InvalidConfiguration(msg)
|
||||
self.network_client = NetworkClient(*client_args)
|
||||
self.hosts_client = HostsClientJSON(*client_args)
|
||||
self.account_client = AccountClient(*client_args)
|
||||
if self.config.service_available.glance:
|
||||
|
||||
@@ -17,7 +17,7 @@ import json
|
||||
from tempest.common.rest_client import RestClient
|
||||
|
||||
|
||||
class NetworkClient(RestClient):
|
||||
class NetworkClientJSON(RestClient):
|
||||
|
||||
"""
|
||||
Tempest REST client for Neutron. Uses v2 of the Neutron API, since the
|
||||
@@ -33,8 +33,8 @@ class NetworkClient(RestClient):
|
||||
"""
|
||||
|
||||
def __init__(self, config, username, password, auth_url, tenant_name=None):
|
||||
super(NetworkClient, self).__init__(config, username, password,
|
||||
auth_url, tenant_name)
|
||||
super(NetworkClientJSON, self).__init__(config, username, password,
|
||||
auth_url, tenant_name)
|
||||
self.service = self.config.network.catalog_type
|
||||
self.version = '2.0'
|
||||
self.uri_prefix = "v%s" % (self.version)
|
||||
@@ -108,15 +108,14 @@ class NetworkClient(RestClient):
|
||||
body = json.loads(body)
|
||||
return resp, body
|
||||
|
||||
def create_port(self, network_id, state=None):
|
||||
if not state:
|
||||
state = True
|
||||
def create_port(self, network_id, **kwargs):
|
||||
post_body = {
|
||||
'port': {
|
||||
'network_id': network_id,
|
||||
'admin_state_up': state,
|
||||
}
|
||||
}
|
||||
for key, val in kwargs.items():
|
||||
post_body['port'][key] = val
|
||||
body = json.dumps(post_body)
|
||||
uri = '%s/ports' % (self.uri_prefix)
|
||||
resp, body = self.post(uri, headers=self.headers, body=body)
|
||||
@@ -244,7 +243,7 @@ class NetworkClient(RestClient):
|
||||
'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'])
|
||||
# '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)
|
||||
|
||||
0
tempest/services/network/xml/__init__.py
Normal file
0
tempest/services/network/xml/__init__.py
Normal file
172
tempest/services/network/xml/network_client.py
Executable file
172
tempest/services/network/xml/network_client.py
Executable file
@@ -0,0 +1,172 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# 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 lxml import etree
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from tempest.common.rest_client import RestClientXML
|
||||
from tempest.services.compute.xml.common import Document
|
||||
from tempest.services.compute.xml.common import Element
|
||||
from tempest.services.compute.xml.common import xml_to_json
|
||||
|
||||
|
||||
class NetworkClientXML(RestClientXML):
|
||||
|
||||
def __init__(self, config, username, password, auth_url, tenant_name=None):
|
||||
super(NetworkClientXML, self).__init__(config, username, password,
|
||||
auth_url, tenant_name)
|
||||
self.service = self.config.network.catalog_type
|
||||
self.version = '2.0'
|
||||
self.uri_prefix = "v%s" % (self.version)
|
||||
|
||||
def list_networks(self):
|
||||
uri = '%s/networks' % (self.uri_prefix)
|
||||
resp, body = self.get(uri, self.headers)
|
||||
networks = self._parse_array(etree.fromstring(body))
|
||||
networks = {"networks": networks}
|
||||
return resp, networks
|
||||
|
||||
def create_network(self, name):
|
||||
uri = '%s/networks' % (self.uri_prefix)
|
||||
post_body = Element("network")
|
||||
p2 = Element("name", name)
|
||||
post_body.append(p2)
|
||||
resp, body = self.post(uri, str(Document(post_body)), self.headers)
|
||||
body = _root_tag_fetcher_and_xml_to_json_parse(body)
|
||||
return resp, body
|
||||
|
||||
def create_bulk_network(self, count, names):
|
||||
uri = '%s/networks' % (self.uri_prefix)
|
||||
post_body = Element("networks")
|
||||
for i in range(count):
|
||||
p1 = Element("network")
|
||||
p2 = Element("name", names[i])
|
||||
p1.append(p2)
|
||||
post_body.append(p1)
|
||||
resp, body = self.post(uri, str(Document(post_body)), self.headers)
|
||||
networks = self._parse_array(etree.fromstring(body))
|
||||
networks = {"networks": networks}
|
||||
return resp, networks
|
||||
|
||||
def delete_network(self, uuid):
|
||||
uri = '%s/networks/%s' % (self.uri_prefix, str(uuid))
|
||||
return self.delete(uri, self.headers)
|
||||
|
||||
def show_network(self, uuid):
|
||||
uri = '%s/networks/%s' % (self.uri_prefix, str(uuid))
|
||||
resp, body = self.get(uri, self.headers)
|
||||
body = _root_tag_fetcher_and_xml_to_json_parse(body)
|
||||
return resp, body
|
||||
|
||||
def create_subnet(self, net_uuid, cidr):
|
||||
uri = '%s/subnets' % (self.uri_prefix)
|
||||
subnet = Element("subnet")
|
||||
p2 = Element("network_id", net_uuid)
|
||||
p3 = Element("cidr", cidr)
|
||||
p4 = Element("ip_version", 4)
|
||||
subnet.append(p2)
|
||||
subnet.append(p3)
|
||||
subnet.append(p4)
|
||||
resp, body = self.post(uri, str(Document(subnet)), self.headers)
|
||||
body = _root_tag_fetcher_and_xml_to_json_parse(body)
|
||||
return resp, body
|
||||
|
||||
def delete_subnet(self, subnet_id):
|
||||
uri = '%s/subnets/%s' % (self.uri_prefix, str(subnet_id))
|
||||
return self.delete(uri, self.headers)
|
||||
|
||||
def list_subnets(self):
|
||||
uri = '%s/subnets' % (self.uri_prefix)
|
||||
resp, body = self.get(uri, self.headers)
|
||||
subnets = self._parse_array(etree.fromstring(body))
|
||||
subnets = {"subnets": subnets}
|
||||
return resp, subnets
|
||||
|
||||
def show_subnet(self, uuid):
|
||||
uri = '%s/subnets/%s' % (self.uri_prefix, str(uuid))
|
||||
resp, body = self.get(uri, self.headers)
|
||||
body = _root_tag_fetcher_and_xml_to_json_parse(body)
|
||||
return resp, body
|
||||
|
||||
def create_port(self, net_uuid, **kwargs):
|
||||
uri = '%s/ports' % (self.uri_prefix)
|
||||
port = Element("port")
|
||||
p1 = Element('network_id', net_uuid)
|
||||
port.append(p1)
|
||||
for key, val in kwargs.items():
|
||||
key = Element(key, val)
|
||||
port.append(key)
|
||||
resp, body = self.post(uri, str(Document(port)), self.headers)
|
||||
body = _root_tag_fetcher_and_xml_to_json_parse(body)
|
||||
return resp, body
|
||||
|
||||
def delete_port(self, port_id):
|
||||
uri = '%s/ports/%s' % (self.uri_prefix, str(port_id))
|
||||
return self.delete(uri, self.headers)
|
||||
|
||||
def _parse_array(self, node):
|
||||
array = []
|
||||
for child in node.getchildren():
|
||||
array.append(xml_to_json(child))
|
||||
return array
|
||||
|
||||
def list_ports(self):
|
||||
url = '%s/ports' % (self.uri_prefix)
|
||||
resp, body = self.get(url, self.headers)
|
||||
ports = self._parse_array(etree.fromstring(body))
|
||||
ports = {"ports": ports}
|
||||
return resp, ports
|
||||
|
||||
def show_port(self, port_id):
|
||||
uri = '%s/ports/%s' % (self.uri_prefix, str(port_id))
|
||||
resp, body = self.get(uri, self.headers)
|
||||
body = _root_tag_fetcher_and_xml_to_json_parse(body)
|
||||
return resp, body
|
||||
|
||||
def update_port(self, port_id, name):
|
||||
uri = '%s/ports/%s' % (self.uri_prefix, str(port_id))
|
||||
port = Element("port")
|
||||
p2 = Element("name", name)
|
||||
port.append(p2)
|
||||
resp, body = self.put(uri, str(Document(port)), self.headers)
|
||||
body = _root_tag_fetcher_and_xml_to_json_parse(body)
|
||||
return resp, body
|
||||
|
||||
def update_subnet(self, subnet_id, name):
|
||||
uri = '%s/subnets/%s' % (self.uri_prefix, str(subnet_id))
|
||||
subnet = Element("subnet")
|
||||
p2 = Element("name", name)
|
||||
subnet.append(p2)
|
||||
resp, body = self.put(uri, str(Document(subnet)), self.headers)
|
||||
body = _root_tag_fetcher_and_xml_to_json_parse(body)
|
||||
return resp, body
|
||||
|
||||
def update_network(self, net_id, name):
|
||||
uri = '%s/networks/%s' % (self.uri_prefix, str(net_id))
|
||||
network = Element("network")
|
||||
p2 = Element("name", name)
|
||||
network.append(p2)
|
||||
resp, body = self.put(uri, str(Document(network)), self.headers)
|
||||
body = _root_tag_fetcher_and_xml_to_json_parse(body)
|
||||
return resp, body
|
||||
|
||||
|
||||
def _root_tag_fetcher_and_xml_to_json_parse(xml_returned_body):
|
||||
body = ET.fromstring(xml_returned_body)
|
||||
root_tag = body.tag
|
||||
if root_tag.startswith("{"):
|
||||
ns, root_tag = root_tag.split("}", 1)
|
||||
body = xml_to_json(etree.fromstring(xml_returned_body))
|
||||
body = {root_tag: body}
|
||||
return body
|
||||
Reference in New Issue
Block a user