Merge " Test port update with new security group"
diff --git a/requirements.txt b/requirements.txt
index a6e7dd1..2af8586 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,7 +6,7 @@
 httplib2>=0.7.5
 jsonschema>=2.0.0,<3.0.0
 testtools>=0.9.36,!=1.2.0
-boto>=2.32.1
+boto>=2.32.1,<2.35.0
 paramiko>=1.13.0
 netaddr>=0.7.12
 python-ceilometerclient>=1.0.6
@@ -20,7 +20,7 @@
 python-saharaclient>=0.7.6
 python-swiftclient>=2.2.0
 testrepository>=0.0.18
-oslo.config>=1.4.0  # Apache-2.0
+oslo.config>=1.6.0  # Apache-2.0
 six>=1.7.0
 iso8601>=0.1.9
 fixtures>=0.3.14
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
     """
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
index cf7ce65..0800b47 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_accounts.py
@@ -22,9 +22,9 @@
 
 from tempest import auth
 from tempest.common import accounts
-from tempest.common import http
 from tempest import config
 from tempest import exceptions
+from tempest.services.identity.json import identity_client
 from tempest.tests import base
 from tempest.tests import fake_config
 from tempest.tests import fake_identity
@@ -68,7 +68,7 @@
         return hash_list
 
     def test_get_hash(self):
-        self.stubs.Set(http.ClosingHttp, 'request',
+        self.stubs.Set(identity_client.TokenClientJSON, 'raw_request',
                        fake_identity._fake_v2_response)
         test_account_class = accounts.Accounts('test_name')
         hash_list = self._get_hash_list(self.test_accounts)
diff --git a/tempest/tests/test_auth.py b/tempest/tests/test_auth.py
index 6a2e335..fc05198 100644
--- a/tempest/tests/test_auth.py
+++ b/tempest/tests/test_auth.py
@@ -19,9 +19,10 @@
 from oslotest import mockpatch
 
 from tempest import auth
-from tempest.common import http
 from tempest import config
 from tempest import exceptions
+from tempest.services.identity.json import identity_client as v2_client
+from tempest.services.identity.v3.json import identity_client as v3_client
 from tempest.tests import base
 from tempest.tests import fake_auth_provider
 from tempest.tests import fake_config
@@ -45,7 +46,6 @@
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.fake_http = fake_http.fake_httplib2(return_type=200)
-        self.stubs.Set(http.ClosingHttp, 'request', self.fake_http.request)
         self.stubs.Set(auth, 'get_credentials',
                        fake_auth_provider.get_credentials)
         self.stubs.Set(auth, 'get_default_credentials',
@@ -125,7 +125,7 @@
 
     def setUp(self):
         super(TestKeystoneV2AuthProvider, self).setUp()
-        self.stubs.Set(http.ClosingHttp, 'request',
+        self.stubs.Set(v2_client.TokenClientJSON, 'raw_request',
                        fake_identity._fake_v2_response)
         self.target_url = 'test_api'
 
@@ -346,7 +346,7 @@
 
     def setUp(self):
         super(TestKeystoneV3AuthProvider, self).setUp()
-        self.stubs.Set(http.ClosingHttp, 'request',
+        self.stubs.Set(v3_client.V3TokenClientJSON, 'raw_request',
                        fake_identity._fake_v3_response)
 
     def _get_fake_alt_identity(self):
diff --git a/tempest/tests/test_credentials.py b/tempest/tests/test_credentials.py
index aa3df36..1abb941 100644
--- a/tempest/tests/test_credentials.py
+++ b/tempest/tests/test_credentials.py
@@ -18,10 +18,11 @@
 from oslo.config import cfg
 
 from tempest import auth
-from tempest.common import http
 from tempest.common import tempest_fixtures as fixtures
 from tempest import config
 from tempest import exceptions
+from tempest.services.identity.json import identity_client as v2_client
+from tempest.services.identity.v3.json import identity_client as v3_client
 from tempest.tests import base
 from tempest.tests import fake_config
 from tempest.tests import fake_identity
@@ -76,10 +77,12 @@
 
     identity_response = fake_identity._fake_v2_response
     credentials_class = auth.KeystoneV2Credentials
+    tokenclient_class = v2_client.TokenClientJSON
 
     def setUp(self):
         super(KeystoneV2CredentialsTests, self).setUp()
-        self.stubs.Set(http.ClosingHttp, 'request', self.identity_response)
+        self.stubs.Set(self.tokenclient_class, 'raw_request',
+                       self.identity_response)
 
     def _verify_credentials(self, credentials_class, filled=True,
                             creds_dict=None):
@@ -185,6 +188,7 @@
 
     credentials_class = auth.KeystoneV3Credentials
     identity_response = fake_identity._fake_v3_response
+    tokenclient_class = v3_client.V3TokenClientJSON
 
     def setUp(self):
         super(KeystoneV3CredentialsTests, self).setUp()
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index 994b4a2..d058fd9 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -15,7 +15,6 @@
 import mock
 from oslo.config import cfg
 
-from tempest.common import http
 from tempest.common import isolated_creds
 from tempest.common import rest_client
 from tempest import config
@@ -36,7 +35,7 @@
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.fake_http = fake_http.fake_httplib2(return_type=200)
-        self.stubs.Set(http.ClosingHttp, 'request',
+        self.stubs.Set(json_iden_client.TokenClientJSON, 'raw_request',
                        fake_identity._fake_v2_response)
         cfg.CONF.set_default('operator_role', 'FakeRole',
                              group='object-storage')