Merge network clients to a single class
There are two network clients as a base one and a JSON one. This
implementation way is different from the other projects' clients.
Now we need to implement a rest client method as a library function,
and it is necessary to make the rest implementations consistent now.
Then, this patch merges network clients to a single class like the
other projects' ones.
Change-Id: I8373f372dcc7b93c185bb5fc67f6a84429505672
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 61a7d2e..20b95e4 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -556,7 +556,7 @@
if not client:
client = self.network_client
if not tenant_id:
- tenant_id = client.rest_client.tenant_id
+ tenant_id = client.tenant_id
name = data_utils.rand_name(namestart)
result = client.create_network(name=name, tenant_id=tenant_id)
network = net_resources.DeletableNetwork(client=client,
@@ -791,7 +791,7 @@
if client is None:
client = self.network_client
if tenant_id is None:
- tenant_id = client.rest_client.tenant_id
+ tenant_id = client.tenant_id
secgroup = self._create_empty_security_group(namestart=namestart,
client=client,
tenant_id=tenant_id)
@@ -817,7 +817,7 @@
if client is None:
client = self.network_client
if not tenant_id:
- tenant_id = client.rest_client.tenant_id
+ tenant_id = client.tenant_id
sg_name = data_utils.rand_name(namestart)
sg_desc = sg_name + " description"
sg_dict = dict(name=sg_name,
@@ -842,7 +842,7 @@
if client is None:
client = self.network_client
if not tenant_id:
- tenant_id = client.rest_client.tenant_id
+ tenant_id = client.tenant_id
sgs = [
sg for sg in client.list_security_groups().values()[0]
if sg['tenant_id'] == tenant_id and sg['name'] == 'default'
@@ -874,7 +874,7 @@
if client is None:
client = self.network_client
if not tenant_id:
- tenant_id = client.rest_client.tenant_id
+ tenant_id = client.tenant_id
if secgroup is None:
secgroup = self._default_security_group(client=client,
tenant_id=tenant_id)
@@ -986,7 +986,7 @@
if not client:
client = self.network_client
if not tenant_id:
- tenant_id = client.rest_client.tenant_id
+ tenant_id = client.tenant_id
router_id = CONF.network.public_router_id
network_id = CONF.network.public_network_id
if router_id:
@@ -1005,7 +1005,7 @@
if not client:
client = self.network_client
if not tenant_id:
- tenant_id = client.rest_client.tenant_id
+ tenant_id = client.tenant_id
name = data_utils.rand_name(namestart)
result = client.create_router(name=name,
admin_state_up=True,
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 0a9a1fa..c622ee4 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -11,12 +11,18 @@
# under the License.
import json
+import time
+import urllib
from tempest.common import rest_client
-from tempest.services.network import network_client_base
+from tempest.common.utils import misc
+from tempest import config
+from tempest import exceptions
+
+CONF = config.CONF
-class NetworkClientJSON(network_client_base.NetworkClientBase):
+class NetworkClientJSON(rest_client.RestClient):
"""
Tempest REST client for Neutron. Uses v2 of the Neutron API, since the
@@ -31,8 +37,228 @@
quotas
"""
- def get_rest_client(self, auth_provider):
- return rest_client.RestClient(auth_provider)
+ def __init__(self, auth_provider):
+ super(NetworkClientJSON, self).__init__(auth_provider)
+ self.service = CONF.network.catalog_type
+ self.build_timeout = CONF.network.build_timeout
+ self.build_interval = CONF.network.build_interval
+ self.version = '2.0'
+ self.uri_prefix = "v%s" % (self.version)
+
+ def get_uri(self, plural_name):
+ # get service prefix from resource name
+
+ # The following list represents resource names that do not require
+ # changing underscore to a hyphen
+ hyphen_exceptions = ["health_monitors", "firewall_rules",
+ "firewall_policies"]
+ # the following map is used to construct proper URI
+ # for the given neutron resource
+ service_resource_prefix_map = {
+ 'networks': '',
+ 'subnets': '',
+ 'ports': '',
+ 'pools': 'lb',
+ 'vips': 'lb',
+ 'health_monitors': 'lb',
+ 'members': 'lb',
+ 'ipsecpolicies': 'vpn',
+ 'vpnservices': 'vpn',
+ 'ikepolicies': 'vpn',
+ 'ipsecpolicies': 'vpn',
+ 'metering_labels': 'metering',
+ 'metering_label_rules': 'metering',
+ 'firewall_rules': 'fw',
+ 'firewall_policies': 'fw',
+ 'firewalls': 'fw'
+ }
+ service_prefix = service_resource_prefix_map.get(
+ plural_name)
+ if plural_name not in hyphen_exceptions:
+ plural_name = plural_name.replace("_", "-")
+ if service_prefix:
+ uri = '%s/%s/%s' % (self.uri_prefix, service_prefix,
+ plural_name)
+ else:
+ uri = '%s/%s' % (self.uri_prefix, plural_name)
+ return uri
+
+ def pluralize(self, resource_name):
+ # get plural from map or just add 's'
+
+ # map from resource name to a plural name
+ # needed only for those which can't be constructed as name + 's'
+ resource_plural_map = {
+ 'security_groups': 'security_groups',
+ 'security_group_rules': 'security_group_rules',
+ 'ipsecpolicy': 'ipsecpolicies',
+ 'ikepolicy': 'ikepolicies',
+ 'ipsecpolicy': 'ipsecpolicies',
+ 'quotas': 'quotas',
+ 'firewall_policy': 'firewall_policies'
+ }
+ return resource_plural_map.get(resource_name, resource_name + 's')
+
+ def _lister(self, plural_name):
+ def _list(**filters):
+ uri = self.get_uri(plural_name)
+ if filters:
+ uri += '?' + urllib.urlencode(filters, doseq=1)
+ resp, body = self.get(uri)
+ result = {plural_name: self.deserialize_list(body)}
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp, result)
+
+ return _list
+
+ def _deleter(self, resource_name):
+ def _delete(resource_id):
+ plural = self.pluralize(resource_name)
+ uri = '%s/%s' % (self.get_uri(plural), resource_id)
+ resp, body = self.delete(uri)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ return _delete
+
+ def _shower(self, resource_name):
+ def _show(resource_id, **fields):
+ # fields is a dict which key is 'fields' and value is a
+ # list of field's name. An example:
+ # {'fields': ['id', 'name']}
+ plural = self.pluralize(resource_name)
+ uri = '%s/%s' % (self.get_uri(plural), resource_id)
+ if fields:
+ uri += '?' + urllib.urlencode(fields, doseq=1)
+ resp, body = self.get(uri)
+ body = self.deserialize_single(body)
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ return _show
+
+ def _creater(self, resource_name):
+ def _create(**kwargs):
+ plural = self.pluralize(resource_name)
+ uri = self.get_uri(plural)
+ post_data = self.serialize({resource_name: kwargs})
+ resp, body = self.post(uri, post_data)
+ body = self.deserialize_single(body)
+ self.expected_success(201, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ return _create
+
+ def _updater(self, resource_name):
+ def _update(res_id, **kwargs):
+ plural = self.pluralize(resource_name)
+ uri = '%s/%s' % (self.get_uri(plural), res_id)
+ post_data = self.serialize({resource_name: kwargs})
+ resp, body = self.put(uri, post_data)
+ body = self.deserialize_single(body)
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ return _update
+
+ def __getattr__(self, name):
+ method_prefixes = ["list_", "delete_", "show_", "create_", "update_"]
+ method_functors = [self._lister,
+ self._deleter,
+ self._shower,
+ self._creater,
+ self._updater]
+ for index, prefix in enumerate(method_prefixes):
+ prefix_len = len(prefix)
+ if name[:prefix_len] == prefix:
+ return method_functors[index](name[prefix_len:])
+ raise AttributeError(name)
+
+ # Common methods that are hard to automate
+ def create_bulk_network(self, names):
+ network_list = [{'name': name} for name in names]
+ post_data = {'networks': network_list}
+ body = self.serialize_list(post_data, "networks", "network")
+ uri = self.get_uri("networks")
+ resp, body = self.post(uri, body)
+ body = {'networks': self.deserialize_list(body)}
+ self.expected_success(201, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def create_bulk_subnet(self, subnet_list):
+ post_data = {'subnets': subnet_list}
+ body = self.serialize_list(post_data, 'subnets', 'subnet')
+ uri = self.get_uri('subnets')
+ resp, body = self.post(uri, body)
+ body = {'subnets': self.deserialize_list(body)}
+ self.expected_success(201, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def create_bulk_port(self, port_list):
+ post_data = {'ports': port_list}
+ body = self.serialize_list(post_data, 'ports', 'port')
+ uri = self.get_uri('ports')
+ resp, body = self.post(uri, body)
+ body = {'ports': self.deserialize_list(body)}
+ self.expected_success(201, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def wait_for_resource_deletion(self, resource_type, id):
+ """Waits for a resource to be deleted."""
+ start_time = int(time.time())
+ while True:
+ if self.is_resource_deleted(resource_type, id):
+ return
+ if int(time.time()) - start_time >= self.build_timeout:
+ raise exceptions.TimeoutException
+ time.sleep(self.build_interval)
+
+ def is_resource_deleted(self, resource_type, id):
+ method = 'show_' + resource_type
+ try:
+ getattr(self, method)(id)
+ except AttributeError:
+ raise Exception("Unknown resource type %s " % resource_type)
+ except exceptions.NotFound:
+ return True
+ return False
+
+ def wait_for_resource_status(self, fetch, status, interval=None,
+ timeout=None):
+ """
+ @summary: Waits for a network resource to reach a status
+ @param fetch: the callable to be used to query the resource status
+ @type fecth: callable that takes no parameters and returns the resource
+ @param status: the status that the resource has to reach
+ @type status: String
+ @param interval: the number of seconds to wait between each status
+ query
+ @type interval: Integer
+ @param timeout: the maximum number of seconds to wait for the resource
+ to reach the desired status
+ @type timeout: Integer
+ """
+ if not interval:
+ interval = self.build_interval
+ if not timeout:
+ timeout = self.build_timeout
+ start_time = time.time()
+
+ while time.time() - start_time <= timeout:
+ resource = fetch()
+ if resource['status'] == status:
+ return
+ time.sleep(interval)
+
+ # At this point, the wait has timed out
+ message = 'Resource %s' % (str(resource))
+ message += ' failed to reach status %s' % status
+ message += ' (current: %s)' % resource['status']
+ message += ' within the required time %s' % timeout
+ caller = misc.find_test_caller()
+ if caller:
+ message = '(%s) %s' % (caller, message)
+ raise exceptions.TimeoutException(message)
def deserialize_single(self, body):
return json.loads(body)
@@ -59,14 +285,14 @@
body = json.dumps(put_body)
uri = '%s/quotas/%s' % (self.uri_prefix, tenant_id)
resp, body = self.put(uri, body)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body['quota'])
def reset_quotas(self, tenant_id):
uri = '%s/quotas/%s' % (self.uri_prefix, tenant_id)
resp, body = self.delete(uri)
- self.rest_client.expected_success(204, resp.status)
+ self.expected_success(204, resp.status)
return rest_client.ResponseBody(resp, body)
def create_router(self, name, admin_state_up=True, **kwargs):
@@ -76,14 +302,14 @@
body = json.dumps(post_body)
uri = '%s/routers' % (self.uri_prefix)
resp, body = self.post(uri, body)
- self.rest_client.expected_success(201, resp.status)
+ self.expected_success(201, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def _update_router(self, router_id, set_enable_snat, **kwargs):
uri = '%s/routers/%s' % (self.uri_prefix, router_id)
resp, body = self.get(uri)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
update_body = {}
update_body['name'] = kwargs.get('name', body['router']['name'])
@@ -103,7 +329,7 @@
update_body = dict(router=update_body)
update_body = json.dumps(update_body)
resp, body = self.put(uri, update_body)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -130,7 +356,7 @@
update_body = {"subnet_id": subnet_id}
update_body = json.dumps(update_body)
resp, body = self.put(uri, update_body)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -140,7 +366,7 @@
update_body = {"port_id": port_id}
update_body = json.dumps(update_body)
resp, body = self.put(uri, update_body)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -150,7 +376,7 @@
update_body = {"subnet_id": subnet_id}
update_body = json.dumps(update_body)
resp, body = self.put(uri, update_body)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -160,7 +386,7 @@
update_body = {"port_id": port_id}
update_body = json.dumps(update_body)
resp, body = self.put(uri, update_body)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -175,7 +401,7 @@
uri = '%s/lb/pools/%s/health_monitors' % (self.uri_prefix,
pool_id)
resp, body = self.post(uri, body)
- self.rest_client.expected_success(201, resp.status)
+ self.expected_success(201, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -184,13 +410,13 @@
uri = '%s/lb/pools/%s/health_monitors/%s' % (self.uri_prefix, pool_id,
health_monitor_id)
resp, body = self.delete(uri)
- self.rest_client.expected_success(204, resp.status)
+ self.expected_success(204, resp.status)
return rest_client.ResponseBody(resp, body)
def list_router_interfaces(self, uuid):
uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
resp, body = self.get(uri)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -203,14 +429,14 @@
agent = {"agent": agent_info}
body = json.dumps(agent)
resp, body = self.put(uri, body)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def list_pools_hosted_by_one_lbaas_agent(self, agent_id):
uri = '%s/agents/%s/loadbalancer-pools' % (self.uri_prefix, agent_id)
resp, body = self.get(uri)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -218,21 +444,21 @@
uri = ('%s/lb/pools/%s/loadbalancer-agent' %
(self.uri_prefix, pool_id))
resp, body = self.get(uri)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def list_routers_on_l3_agent(self, agent_id):
uri = '%s/agents/%s/l3-routers' % (self.uri_prefix, agent_id)
resp, body = self.get(uri)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def list_l3_agents_hosting_router(self, router_id):
uri = '%s/routers/%s/l3-agents' % (self.uri_prefix, router_id)
resp, body = self.get(uri)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -241,7 +467,7 @@
post_body = {"router_id": router_id}
body = json.dumps(post_body)
resp, body = self.post(uri, body)
- self.rest_client.expected_success(201, resp.status)
+ self.expected_success(201, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -249,20 +475,20 @@
uri = '%s/agents/%s/l3-routers/%s' % (
self.uri_prefix, agent_id, router_id)
resp, body = self.delete(uri)
- self.rest_client.expected_success(204, resp.status)
+ self.expected_success(204, resp.status)
return rest_client.ResponseBody(resp, body)
def list_dhcp_agent_hosting_network(self, network_id):
uri = '%s/networks/%s/dhcp-agents' % (self.uri_prefix, network_id)
resp, body = self.get(uri)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def list_networks_hosted_by_one_dhcp_agent(self, agent_id):
uri = '%s/agents/%s/dhcp-networks' % (self.uri_prefix, agent_id)
resp, body = self.get(uri)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -270,7 +496,7 @@
uri = '%s/agents/%s/dhcp-networks/%s' % (self.uri_prefix, agent_id,
network_id)
resp, body = self.delete(uri)
- self.rest_client.expected_success(204, resp.status)
+ self.expected_success(204, resp.status)
return rest_client.ResponseBody(resp, body)
def create_ikepolicy(self, name, **kwargs):
@@ -284,7 +510,7 @@
body = json.dumps(post_body)
uri = '%s/vpn/ikepolicies' % (self.uri_prefix)
resp, body = self.post(uri, body)
- self.rest_client.expected_success(201, resp.status)
+ self.expected_success(201, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -298,7 +524,7 @@
}
body = json.dumps(put_body)
resp, body = self.put(uri, body)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -312,14 +538,14 @@
}
body = json.dumps(put_body)
resp, body = self.put(uri, body)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def list_lb_pool_stats(self, pool_id):
uri = '%s/lb/pools/%s/stats' % (self.uri_prefix, pool_id)
resp, body = self.get(uri)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -328,7 +554,7 @@
body = json.dumps(post_body)
uri = '%s/agents/%s/dhcp-networks' % (self.uri_prefix, agent_id)
resp, body = self.post(uri, body)
- self.rest_client.expected_success(201, resp.status)
+ self.expected_success(201, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -344,7 +570,7 @@
}
body = json.dumps(body)
resp, body = self.put(uri, body)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -355,6 +581,6 @@
update_body = {"firewall_rule_id": firewall_rule_id}
update_body = json.dumps(update_body)
resp, body = self.put(uri, update_body)
- self.rest_client.expected_success(200, resp.status)
+ self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/network/network_client_base.py b/tempest/services/network/network_client_base.py
deleted file mode 100644
index 53fd222..0000000
--- a/tempest/services/network/network_client_base.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# 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.
-
-import time
-import urllib
-
-from tempest.common import rest_client
-from tempest.common.utils import misc
-from tempest import config
-from tempest import exceptions
-
-CONF = config.CONF
-
-# the following map is used to construct proper URI
-# for the given neutron resource
-service_resource_prefix_map = {
- 'networks': '',
- 'subnets': '',
- 'ports': '',
- 'pools': 'lb',
- 'vips': 'lb',
- 'health_monitors': 'lb',
- 'members': 'lb',
- 'ipsecpolicies': 'vpn',
- 'vpnservices': 'vpn',
- 'ikepolicies': 'vpn',
- 'ipsecpolicies': 'vpn',
- 'metering_labels': 'metering',
- 'metering_label_rules': 'metering',
- 'firewall_rules': 'fw',
- 'firewall_policies': 'fw',
- 'firewalls': 'fw'
-}
-
-# The following list represents resource names that do not require
-# changing underscore to a hyphen
-hyphen_exceptions = ["health_monitors", "firewall_rules", "firewall_policies"]
-
-# map from resource name to a plural name
-# needed only for those which can't be constructed as name + 's'
-resource_plural_map = {
- 'security_groups': 'security_groups',
- 'security_group_rules': 'security_group_rules',
- 'ipsecpolicy': 'ipsecpolicies',
- 'ikepolicy': 'ikepolicies',
- 'ipsecpolicy': 'ipsecpolicies',
- 'quotas': 'quotas',
- 'firewall_policy': 'firewall_policies'
-}
-
-
-class NetworkClientBase(object):
- def __init__(self, auth_provider):
- self.rest_client = self.get_rest_client(
- auth_provider)
- self.rest_client.service = CONF.network.catalog_type
- self.version = '2.0'
- self.uri_prefix = "v%s" % (self.version)
- self.build_timeout = CONF.network.build_timeout
- self.build_interval = CONF.network.build_interval
-
- def get_rest_client(self, auth_provider):
- raise NotImplementedError
-
- def post(self, uri, body, headers=None):
- return self.rest_client.post(uri, body, headers)
-
- def put(self, uri, body, headers=None):
- return self.rest_client.put(uri, body, headers)
-
- def get(self, uri, headers=None):
- return self.rest_client.get(uri, headers)
-
- def delete(self, uri, headers=None):
- return self.rest_client.delete(uri, headers)
-
- def deserialize_list(self, body):
- raise NotImplementedError
-
- def deserialize_single(self, body):
- raise NotImplementedError
-
- def get_uri(self, plural_name):
- # get service prefix from resource name
- service_prefix = service_resource_prefix_map.get(
- plural_name)
- if plural_name not in hyphen_exceptions:
- plural_name = plural_name.replace("_", "-")
- if service_prefix:
- uri = '%s/%s/%s' % (self.uri_prefix, service_prefix,
- plural_name)
- else:
- uri = '%s/%s' % (self.uri_prefix, plural_name)
- return uri
-
- def pluralize(self, resource_name):
- # get plural from map or just add 's'
- return resource_plural_map.get(resource_name, resource_name + 's')
-
- def _lister(self, plural_name):
- def _list(**filters):
- uri = self.get_uri(plural_name)
- if filters:
- uri += '?' + urllib.urlencode(filters, doseq=1)
- resp, body = self.get(uri)
- result = {plural_name: self.deserialize_list(body)}
- self.rest_client.expected_success(200, resp.status)
- return rest_client.ResponseBody(resp, result)
-
- return _list
-
- def _deleter(self, resource_name):
- def _delete(resource_id):
- plural = self.pluralize(resource_name)
- uri = '%s/%s' % (self.get_uri(plural), resource_id)
- resp, body = self.delete(uri)
- self.rest_client.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- return _delete
-
- def _shower(self, resource_name):
- def _show(resource_id, **fields):
- # fields is a dict which key is 'fields' and value is a
- # list of field's name. An example:
- # {'fields': ['id', 'name']}
- plural = self.pluralize(resource_name)
- uri = '%s/%s' % (self.get_uri(plural), resource_id)
- if fields:
- uri += '?' + urllib.urlencode(fields, doseq=1)
- resp, body = self.get(uri)
- body = self.deserialize_single(body)
- self.rest_client.expected_success(200, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- return _show
-
- def _creater(self, resource_name):
- def _create(**kwargs):
- plural = self.pluralize(resource_name)
- uri = self.get_uri(plural)
- post_data = self.serialize({resource_name: kwargs})
- resp, body = self.post(uri, post_data)
- body = self.deserialize_single(body)
- self.rest_client.expected_success(201, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- return _create
-
- def _updater(self, resource_name):
- def _update(res_id, **kwargs):
- plural = self.pluralize(resource_name)
- uri = '%s/%s' % (self.get_uri(plural), res_id)
- post_data = self.serialize({resource_name: kwargs})
- resp, body = self.put(uri, post_data)
- body = self.deserialize_single(body)
- self.rest_client.expected_success(200, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- return _update
-
- def __getattr__(self, name):
- method_prefixes = ["list_", "delete_", "show_", "create_", "update_"]
- method_functors = [self._lister,
- self._deleter,
- self._shower,
- self._creater,
- self._updater]
- for index, prefix in enumerate(method_prefixes):
- prefix_len = len(prefix)
- if name[:prefix_len] == prefix:
- return method_functors[index](name[prefix_len:])
- raise AttributeError(name)
-
- # Common methods that are hard to automate
- def create_bulk_network(self, names):
- network_list = [{'name': name} for name in names]
- post_data = {'networks': network_list}
- body = self.serialize_list(post_data, "networks", "network")
- uri = self.get_uri("networks")
- resp, body = self.post(uri, body)
- body = {'networks': self.deserialize_list(body)}
- self.rest_client.expected_success(201, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def create_bulk_subnet(self, subnet_list):
- post_data = {'subnets': subnet_list}
- body = self.serialize_list(post_data, 'subnets', 'subnet')
- uri = self.get_uri('subnets')
- resp, body = self.post(uri, body)
- body = {'subnets': self.deserialize_list(body)}
- self.rest_client.expected_success(201, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def create_bulk_port(self, port_list):
- post_data = {'ports': port_list}
- body = self.serialize_list(post_data, 'ports', 'port')
- uri = self.get_uri('ports')
- resp, body = self.post(uri, body)
- body = {'ports': self.deserialize_list(body)}
- self.rest_client.expected_success(201, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def wait_for_resource_deletion(self, resource_type, id):
- """Waits for a resource to be deleted."""
- start_time = int(time.time())
- while True:
- if self.is_resource_deleted(resource_type, id):
- return
- if int(time.time()) - start_time >= self.build_timeout:
- raise exceptions.TimeoutException
- time.sleep(self.build_interval)
-
- def is_resource_deleted(self, resource_type, id):
- method = 'show_' + resource_type
- try:
- getattr(self, method)(id)
- except AttributeError:
- raise Exception("Unknown resource type %s " % resource_type)
- except exceptions.NotFound:
- return True
- return False
-
- def wait_for_resource_status(self, fetch, status, interval=None,
- timeout=None):
- """
- @summary: Waits for a network resource to reach a status
- @param fetch: the callable to be used to query the resource status
- @type fecth: callable that takes no parameters and returns the resource
- @param status: the status that the resource has to reach
- @type status: String
- @param interval: the number of seconds to wait between each status
- query
- @type interval: Integer
- @param timeout: the maximum number of seconds to wait for the resource
- to reach the desired status
- @type timeout: Integer
- """
- if not interval:
- interval = self.build_interval
- if not timeout:
- timeout = self.build_timeout
- start_time = time.time()
-
- while time.time() - start_time <= timeout:
- resource = fetch()
- if resource['status'] == status:
- return
- time.sleep(interval)
-
- # At this point, the wait has timed out
- message = 'Resource %s' % (str(resource))
- message += ' failed to reach status %s' % status
- message += ' (current: %s)' % resource['status']
- message += ' within the required time %s' % timeout
- caller = misc.find_test_caller()
- if caller:
- message = '(%s) %s' % (caller, message)
- raise exceptions.TimeoutException(message)
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index f29ae5a..053dae1 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -320,8 +320,8 @@
return_values = (fake_http.fake_httplib({}, status=204), {})
remove_secgroup_mock = self.patch(
- 'tempest.services.network.network_client_base.'
- 'NetworkClientBase.delete', return_value=return_values)
+ 'tempest.services.network.json.network_client.'
+ 'NetworkClientJSON.delete', return_value=return_values)
iso_creds.clear_isolated_creds()
# Verify default security group delete
calls = remove_secgroup_mock.mock_calls