Merge "Updated from global requirements"
diff --git a/tempest/api/network/admin/test_external_networks_negative.py b/tempest/api/network/admin/test_external_networks_negative.py
new file mode 100644
index 0000000..7dbb347
--- /dev/null
+++ b/tempest/api/network/admin/test_external_networks_negative.py
@@ -0,0 +1,53 @@
+# Copyright 2014 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 import config
+from tempest import exceptions
+from tempest import test
+
+CONF = config.CONF
+
+
+class ExternalNetworksAdminNegativeTestJSON(base.BaseAdminNetworkTest):
+ _interface = 'json'
+
+ @test.attr(type=['negative'])
+ def test_create_port_with_precreated_floatingip_as_fixed_ip(self):
+ """
+ External networks can be used to create both floating-ip as well
+ as instance-ip. So, creating an instance-ip with a value of a
+ pre-created floating-ip should be denied.
+ """
+
+ # create a floating ip
+ client = self.admin_client
+ body = client.create_floatingip(
+ floating_network_id=CONF.network.public_network_id)
+ created_floating_ip = body['floatingip']
+ self.addCleanup(self._try_delete_resource,
+ client.delete_floatingip,
+ created_floating_ip['id'])
+ floating_ip_address = created_floating_ip['floating_ip_address']
+ self.assertIsNotNone(floating_ip_address)
+
+ # use the same value of floatingip as fixed-ip to create_port()
+ fixed_ips = [{'ip_address': floating_ip_address}]
+
+ # create a port which will internally create an instance-ip
+ self.assertRaises(exceptions.Conflict,
+ client.create_port,
+ network_id=CONF.network.public_network_id,
+ fixed_ips=fixed_ips)
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 3802c9d..8fac6c3 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -25,12 +25,9 @@
from tempest.common import http
from tempest.common.utils import misc as misc_utils
-from tempest import config
from tempest import exceptions
from tempest.openstack.common import log as logging
-CONF = config.CONF
-
# redrive rate limited calls at most twice
MAX_RECURSION_DEPTH = 2
@@ -80,13 +77,16 @@
def __init__(self, auth_provider, service, region,
endpoint_type='publicURL',
- build_interval=1, build_timeout=60):
+ build_interval=1, build_timeout=60,
+ disable_ssl_certificate_validation=False, ca_certs=None,
+ trace_requests=''):
self.auth_provider = auth_provider
self.service = service
self.region = region
self.endpoint_type = endpoint_type
self.build_interval = build_interval
self.build_timeout = build_timeout
+ self.trace_requests = trace_requests
# The version of the API this client implements
self.api_version = None
@@ -99,8 +99,7 @@
'location', 'proxy-authenticate',
'retry-after', 'server',
'vary', 'www-authenticate'))
- dscv = CONF.identity.disable_ssl_certificate_validation
- ca_certs = CONF.identity.ca_certificates_file
+ dscv = disable_ssl_certificate_validation
self.http_obj = http.ClosingHttp(
disable_ssl_certificate_validation=dscv, ca_certs=ca_certs)
@@ -117,10 +116,10 @@
def __str__(self):
STRING_LIMIT = 80
- str_format = ("config:%s, service:%s, base_url:%s, "
+ str_format = ("service:%s, base_url:%s, "
"filters: %s, build_interval:%s, build_timeout:%s"
"\ntoken:%s..., \nheaders:%s...")
- return str_format % (CONF, self.service, self.base_url,
+ return str_format % (self.service, self.base_url,
self.filters, self.build_interval,
self.build_timeout,
str(self.token)[0:STRING_LIMIT],
@@ -253,8 +252,7 @@
if req_headers is None:
req_headers = {}
caller_name = misc_utils.find_test_caller()
- trace_regex = CONF.debug.trace_requests
- if trace_regex and re.search(trace_regex, caller_name):
+ if self.trace_requests and re.search(self.trace_requests, caller_name):
self.LOG.debug('Starting Request (%s): %s %s' %
(caller_name, method, req_url))
@@ -375,7 +373,7 @@
# Do the actual request, and time it
start = time.time()
self._log_request_start(method, req_url)
- resp, resp_body = self.http_obj.request(
+ resp, resp_body = self.raw_request(
req_url, method, headers=req_headers, body=req_body)
end = time.time()
self._log_request(method, req_url, resp, secs=(end - start),
@@ -387,6 +385,10 @@
return resp, resp_body
+ def raw_request(self, url, method, headers=None, body=None):
+ return self.http_obj.request(url, method,
+ headers=headers, body=body)
+
def request(self, method, url, extra_headers=False, headers=None,
body=None):
# if extra_headers is True
diff --git a/tempest/common/service_client.py b/tempest/common/service_client.py
new file mode 100644
index 0000000..0572a1f
--- /dev/null
+++ b/tempest/common/service_client.py
@@ -0,0 +1,38 @@
+# Copyright 2015 NEC Corporation. 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.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class ServiceClient(rest_client.RestClient):
+
+ def __init__(self, auth_provider, service, region,
+ endpoint_type=None, build_interval=None, build_timeout=None):
+ params = {
+ 'disable_ssl_certificate_validation':
+ CONF.identity.disable_ssl_certificate_validation,
+ 'ca_certs': CONF.identity.ca_certificates_file,
+ 'trace_requests': CONF.debug.trace_requests
+ }
+ if endpoint_type is not None:
+ params.update({'endpoint_type': endpoint_type})
+ if build_interval is not None:
+ params.update({'build_interval': build_interval})
+ if build_timeout is not None:
+ params.update({'build_timeout': build_timeout})
+ super(ServiceClient, self).__init__(auth_provider, service, region,
+ **params)
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
index c1ebba5..a0ffd28 100644
--- a/tempest/services/baremetal/base.py
+++ b/tempest/services/baremetal/base.py
@@ -16,7 +16,7 @@
import six
-from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
CONF = config.CONF
@@ -42,7 +42,7 @@
return wrapper
-class BaremetalClient(rest_client.RestClient):
+class BaremetalClient(service_client.ServiceClient):
"""
Base Tempest REST client for Ironic API.
diff --git a/tempest/services/compute/json/base.py b/tempest/services/compute/json/base.py
index cb4915b..ae44ffb 100644
--- a/tempest/services/compute/json/base.py
+++ b/tempest/services/compute/json/base.py
@@ -12,13 +12,13 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
CONF = config.CONF
-class ComputeClient(rest_client.RestClient):
+class ComputeClient(service_client.ServiceClient):
"""
Base compute client class
"""
diff --git a/tempest/services/data_processing/v1_1/client.py b/tempest/services/data_processing/v1_1/client.py
index 1b6842d..55b6be6 100644
--- a/tempest/services/data_processing/v1_1/client.py
+++ b/tempest/services/data_processing/v1_1/client.py
@@ -14,13 +14,13 @@
import json
-from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
CONF = config.CONF
-class DataProcessingClient(rest_client.RestClient):
+class DataProcessingClient(service_client.ServiceClient):
def __init__(self, auth_provider):
super(DataProcessingClient, self).__init__(
diff --git a/tempest/services/database/json/flavors_client.py b/tempest/services/database/json/flavors_client.py
index 01be29a..9a27443 100644
--- a/tempest/services/database/json/flavors_client.py
+++ b/tempest/services/database/json/flavors_client.py
@@ -15,13 +15,13 @@
import urllib
-from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
CONF = config.CONF
-class DatabaseFlavorsClientJSON(rest_client.RestClient):
+class DatabaseFlavorsClientJSON(service_client.ServiceClient):
def __init__(self, auth_provider):
super(DatabaseFlavorsClientJSON, self).__init__(
diff --git a/tempest/services/database/json/versions_client.py b/tempest/services/database/json/versions_client.py
index 8a408e9..f5c5217 100644
--- a/tempest/services/database/json/versions_client.py
+++ b/tempest/services/database/json/versions_client.py
@@ -15,13 +15,13 @@
import urllib
-from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
CONF = config.CONF
-class DatabaseVersionsClientJSON(rest_client.RestClient):
+class DatabaseVersionsClientJSON(service_client.ServiceClient):
def __init__(self, auth_provider):
super(DatabaseVersionsClientJSON, self).__init__(
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index f6c77e1..a3ff92d 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -13,13 +13,14 @@
import json
from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
from tempest import exceptions
CONF = config.CONF
-class IdentityClientJSON(rest_client.RestClient):
+class IdentityClientJSON(service_client.ServiceClient):
def __init__(self, auth_provider):
super(IdentityClientJSON, self).__init__(
@@ -340,8 +341,8 @@
except (ValueError, TypeError):
headers = self.get_headers(accept_type="json")
- resp, resp_body = self.http_obj.request(url, method,
- headers=headers, body=body)
+ resp, resp_body = self.raw_request(url, method,
+ headers=headers, body=body)
self._log_request(method, url, resp)
if resp.status in [401, 403]:
diff --git a/tempest/services/identity/v3/json/base.py b/tempest/services/identity/v3/json/base.py
index 30d3886..cba480a 100644
--- a/tempest/services/identity/v3/json/base.py
+++ b/tempest/services/identity/v3/json/base.py
@@ -12,13 +12,13 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
CONF = config.CONF
-class IdentityV3Client(rest_client.RestClient):
+class IdentityV3Client(service_client.ServiceClient):
"""
Base identity v3 client class
"""
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 59902bb..17ad718 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -17,6 +17,7 @@
import urllib
from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
from tempest import exceptions
from tempest.services.identity.v3.json import base
@@ -520,7 +521,7 @@
return rest_client.ResponseBody(resp, body)
-class V3TokenClientJSON(rest_client.RestClient):
+class V3TokenClientJSON(service_client.ServiceClient):
def __init__(self):
super(V3TokenClientJSON, self).__init__(None, None, None)
@@ -605,8 +606,8 @@
except (ValueError, TypeError):
headers = self.get_headers(accept_type="json")
- resp, resp_body = self.http_obj.request(url, method,
- headers=headers, body=body)
+ resp, resp_body = self.raw_request(url, method,
+ headers=headers, body=body)
self._log_request(method, url, resp)
if resp.status in [401, 403]:
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index 0d35ef5..06ba4f7 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -22,6 +22,7 @@
from tempest.common import glance_http
from tempest.common import rest_client
+from tempest.common import service_client
from tempest.common.utils import misc as misc_utils
from tempest import config
from tempest import exceptions
@@ -32,7 +33,7 @@
LOG = logging.getLogger(__name__)
-class ImageClientJSON(rest_client.RestClient):
+class ImageClientJSON(service_client.ServiceClient):
def __init__(self, auth_provider):
super(ImageClientJSON, self).__init__(
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 852832b..b469fac 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -20,13 +20,14 @@
from tempest.common import glance_http
from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
from tempest import exceptions
CONF = config.CONF
-class ImageClientV2JSON(rest_client.RestClient):
+class ImageClientV2JSON(service_client.ServiceClient):
def __init__(self, auth_provider):
super(ImageClientV2JSON, self).__init__(
diff --git a/tempest/services/messaging/json/messaging_client.py b/tempest/services/messaging/json/messaging_client.py
index 45534c7..c4c9f09 100644
--- a/tempest/services/messaging/json/messaging_client.py
+++ b/tempest/services/messaging/json/messaging_client.py
@@ -17,7 +17,7 @@
import urllib
from tempest.api_schema.response.messaging.v1 import queues as queues_schema
-from tempest.common import rest_client
+from tempest.common import service_client
from tempest.common.utils import data_utils
from tempest import config
@@ -25,7 +25,7 @@
CONF = config.CONF
-class MessagingClientJSON(rest_client.RestClient):
+class MessagingClientJSON(service_client.ServiceClient):
def __init__(self, auth_provider):
super(MessagingClientJSON, self).__init__(
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 8f5ed5a..0f2941b 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -15,6 +15,7 @@
import urllib
from tempest.common import rest_client
+from tempest.common import service_client
from tempest.common.utils import misc
from tempest import config
from tempest import exceptions
@@ -22,7 +23,7 @@
CONF = config.CONF
-class NetworkClientJSON(rest_client.RestClient):
+class NetworkClientJSON(service_client.ServiceClient):
"""
Tempest REST client for Neutron. Uses v2 of the Neutron API, since the
diff --git a/tempest/services/object_storage/base.py b/tempest/services/object_storage/base.py
index 655596f..1e7355e 100644
--- a/tempest/services/object_storage/base.py
+++ b/tempest/services/object_storage/base.py
@@ -12,13 +12,13 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
CONF = config.CONF
-class ObjectStorageClient(rest_client.RestClient):
+class ObjectStorageClient(service_client.ServiceClient):
"""
Base object storage client class
"""
diff --git a/tempest/services/orchestration/json/orchestration_client.py b/tempest/services/orchestration/json/orchestration_client.py
index 054f410..d23d934 100644
--- a/tempest/services/orchestration/json/orchestration_client.py
+++ b/tempest/services/orchestration/json/orchestration_client.py
@@ -18,14 +18,14 @@
import time
import urllib
-from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
from tempest import exceptions
CONF = config.CONF
-class OrchestrationClient(rest_client.RestClient):
+class OrchestrationClient(service_client.ServiceClient):
def __init__(self, auth_provider):
super(OrchestrationClient, self).__init__(
diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py
index 2b5dc1a..2bbd88d 100644
--- a/tempest/services/telemetry/json/telemetry_client.py
+++ b/tempest/services/telemetry/json/telemetry_client.py
@@ -15,14 +15,14 @@
import urllib
-from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
from tempest.openstack.common import jsonutils as json
CONF = config.CONF
-class TelemetryClientJSON(rest_client.RestClient):
+class TelemetryClientJSON(service_client.ServiceClient):
def __init__(self, auth_provider):
super(TelemetryClientJSON, self).__init__(
diff --git a/tempest/services/volume/json/base.py b/tempest/services/volume/json/base.py
index ef316f2..e6c72eb 100644
--- a/tempest/services/volume/json/base.py
+++ b/tempest/services/volume/json/base.py
@@ -12,13 +12,13 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.common import rest_client
+from tempest.common import service_client
from tempest import config
CONF = config.CONF
-class VolumeClient(rest_client.RestClient):
+class VolumeClient(service_client.ServiceClient):
"""
Base volume client class
"""