Merge "Fix ambiguous method name"
diff --git a/tempest/api/volume/admin/test_volume_services.py b/tempest/api/volume/admin/test_volume_services.py
index 47130de..755365d 100644
--- a/tempest/api/volume/admin/test_volume_services.py
+++ b/tempest/api/volume/admin/test_volume_services.py
@@ -12,9 +12,6 @@
# 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.lib import decorators
-
from tempest.api.volume import base
from tempest import config
from tempest import test
@@ -23,6 +20,12 @@
CONF = config.CONF
+def _get_host(host):
+ if CONF.volume_feature_enabled.volume_services:
+ host = host.split('@')[0]
+ return host
+
+
class VolumesServicesV2TestJSON(base.BaseVolumeAdminTest):
"""Tests Volume Services API.
@@ -34,7 +37,10 @@
super(VolumesServicesV2TestJSON, cls).resource_setup()
cls.services = (cls.admin_volume_services_client.list_services()
['services'])
- cls.host_name = cls.services[0]['host']
+ # NOTE: Cinder service-list API returns the list contains
+ # "<host name>@<driver name>" like "nova-compute01@lvmdriver-1".
+ # So here picks <host name> up as a host.
+ cls.host_name = _get_host(cls.services[0]['host'])
cls.binary_name = cls.services[0]['binary']
@test.idempotent_id('e0218299-0a59-4f43-8b2b-f1c035b3d26d')
@@ -51,16 +57,10 @@
for service in services:
self.assertEqual(self.binary_name, service['binary'])
- @decorators.skip_because(bug="1530144")
@test.idempotent_id('178710e4-7596-4e08-9333-745cb8bc4f8d')
def test_get_service_by_host_name(self):
- def get_host(host):
- if CONF.volume_feature_enabled.volume_services:
- host = host.split('@')[0]
- return host
-
services_on_host = [service for service in self.services if
- get_host(service['host']) == self.host_name]
+ _get_host(service['host']) == self.host_name]
services = (self.admin_volume_services_client.list_services(
host=self.host_name)['services'])
@@ -80,7 +80,7 @@
host=self.host_name, binary=self.binary_name))['services']
self.assertEqual(1, len(services))
- self.assertEqual(self.host_name, services[0]['host'])
+ self.assertEqual(self.host_name, _get_host(services[0]['host']))
self.assertEqual(self.binary_name, services[0]['binary'])
diff --git a/tempest/clients.py b/tempest/clients.py
index 60baca6..e88a016 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -122,7 +122,8 @@
EndPointClient as EndPointV3Client
from tempest.services.identity.v3.json.groups_client import \
GroupsClient as GroupsV3Client
-from tempest.services.identity.v3.json.identity_client import IdentityV3Client
+from tempest.services.identity.v3.json.identity_client import \
+ IdentityClient as IdentityV3Client
from tempest.services.identity.v3.json.policies_client import \
PoliciesClient as PoliciesV3Client
from tempest.services.identity.v3.json.projects_client import ProjectsClient
@@ -133,7 +134,8 @@
from tempest.services.identity.v3.json.services_client import \
ServicesClient as IdentityServicesV3Client
from tempest.services.identity.v3.json.trusts_client import TrustsClient
-from tempest.services.identity.v3.json.users_clients import UsersV3Client
+from tempest.services.identity.v3.json.users_clients import \
+ UsersClient as UsersV3Client
from tempest.services.image.v1.json.images_client import ImagesClient
from tempest.services.image.v2.json.images_client import ImagesClientV2
from tempest.services.network.json.network_client import NetworkClient
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index e474d86..95be89e 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -756,7 +756,7 @@
# we cannot assume they all have the same signature so we need to discard
# the unused response first value it two values are being returned.
body = get_resources()
- if type(body) == tuple:
+ if isinstance(body, tuple):
body = body[1]
if isinstance(body, dict):
body = body[resource]
diff --git a/tempest/lib/auth.py b/tempest/lib/auth.py
index 806acb5..0586346 100644
--- a/tempest/lib/auth.py
+++ b/tempest/lib/auth.py
@@ -323,10 +323,10 @@
parts = urlparse.urlparse(_base_url)
if filters.get('api_version', None) is not None:
- path = "/" + filters['api_version']
- noversion_path = "/".join(parts.path.split("/")[2:])
- if noversion_path != "":
- path += "/" + noversion_path
+ path = re.sub(r'(^|/)+v\d+(?:\.\d+)?',
+ '/' + filters['api_version'],
+ parts.path,
+ count=1)
_base_url = _base_url.replace(parts.path, path)
if filters.get('skip_path', None) is not None and parts.path != '':
_base_url = _base_url.replace(parts.path, "/")
@@ -445,10 +445,10 @@
parts = urlparse.urlparse(_base_url)
if filters.get('api_version', None) is not None:
- path = "/" + filters['api_version']
- noversion_path = "/".join(parts.path.split("/")[2:])
- if noversion_path != "":
- path += "/" + noversion_path
+ path = re.sub(r'(^|/)+v\d+(?:\.\d+)?',
+ '/' + filters['api_version'],
+ parts.path,
+ count=1)
_base_url = _base_url.replace(parts.path, path)
if filters.get('skip_path', None) is not None:
_base_url = _base_url.replace(parts.path, "/")
diff --git a/tempest/lib/cmd/check_uuid.py b/tempest/lib/cmd/check_uuid.py
index 3adeecd..be3aa49 100755
--- a/tempest/lib/cmd/check_uuid.py
+++ b/tempest/lib/cmd/check_uuid.py
@@ -173,9 +173,9 @@
@staticmethod
def _import_name(node):
- if type(node) == ast.Import:
+ if isinstance(node, ast.Import):
return node.names[0].name
- elif type(node) == ast.ImportFrom:
+ elif isinstance(node, ast.ImportFrom):
return '%s.%s' % (node.module, node.names[0].name)
def _add_import_for_test_uuid(self, patcher, src_parsed, source_path):
diff --git a/tempest/lib/services/compute/versions_client.py b/tempest/lib/services/compute/versions_client.py
index 5898f93..ed82c74 100644
--- a/tempest/lib/services/compute/versions_client.py
+++ b/tempest/lib/services/compute/versions_client.py
@@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import re
+
from oslo_serialization import jsonutils as json
from six.moves import urllib
@@ -22,14 +24,17 @@
class VersionsClient(rest_client.RestClient):
def _get_base_version_url(self):
- # NOTE: The URL which is gotten from keystone's catalog contains
- # API version and project-id like "v2/{project-id}", but we need
- # to access the URL which doesn't contain them for getting API
- # versions. For that, here should use raw_request() instead of
- # get().
+ # NOTE: The URL which is got from keystone's catalog contains
+ # API version and project-id like "/app-name/v2/{project-id}" or
+ # "/v2/{project-id}", but we need to access the URL which doesn't
+ # contain API version for getting API versions. For that, here
+ # should use raw_request() instead of get().
endpoint = self.base_url
- url = urllib.parse.urlparse(endpoint)
- return '%s://%s/' % (url.scheme, url.netloc)
+ url = urllib.parse.urlsplit(endpoint)
+ new_path = re.split(r'(^|/)+v\d+(\.\d+)?', url.path)[0]
+ url = list(url)
+ url[2] = new_path + '/'
+ return urllib.parse.urlunsplit(url)
def list_versions(self):
version_url = self._get_base_version_url()
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 4ce57db..71bb50e 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from oslo_log import log as logging
+
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
@@ -17,6 +19,7 @@
from tempest import test
CONF = config.CONF
+LOG = logging.getLogger(__name__)
class TestVolumeBootPattern(manager.ScenarioTest):
@@ -32,6 +35,11 @@
* Boot an additional instance from the new snapshot based volume
* Check written content in the instance booted from snapshot
"""
+
+ # Boot from volume scenario is quite slow, and needs extra
+ # breathing room to get through deletes in the time allotted.
+ TIMEOUT_SCALING_FACTOR = 2
+
@classmethod
def skip_checks(cls):
super(TestVolumeBootPattern, cls).skip_checks()
@@ -101,42 +109,53 @@
@test.attr(type='smoke')
@test.services('compute', 'volume', 'image')
def test_volume_boot_pattern(self):
+ LOG.info("Creating keypair and security group")
keypair = self.create_keypair()
security_group = self._create_security_group()
# create an instance from volume
+ LOG.info("Booting instance 1 from volume")
volume_origin = self._create_volume_from_image()
instance_1st = self._boot_instance_from_volume(volume_origin['id'],
keypair, security_group)
+ LOG.info("Booted first instance: %s" % instance_1st)
# write content to volume on instance
+ LOG.info("Setting timestamp in instance %s" % instance_1st)
ip_instance_1st = self.get_server_ip(instance_1st)
timestamp = self.create_timestamp(ip_instance_1st,
private_key=keypair['private_key'])
# delete instance
+ LOG.info("Deleting first instance: %s" % instance_1st)
self._delete_server(instance_1st)
# create a 2nd instance from volume
instance_2nd = self._boot_instance_from_volume(volume_origin['id'],
keypair, security_group)
+ LOG.info("Booted second instance %s" % instance_2nd)
# check the content of written file
+ LOG.info("Getting timestamp in instance %s" % instance_2nd)
ip_instance_2nd = self.get_server_ip(instance_2nd)
timestamp2 = self.get_timestamp(ip_instance_2nd,
private_key=keypair['private_key'])
self.assertEqual(timestamp, timestamp2)
# snapshot a volume
+ LOG.info("Creating snapshot from volume: %s" % volume_origin['id'])
snapshot = self._create_snapshot_from_volume(volume_origin['id'])
# create a 3rd instance from snapshot
+ LOG.info("Creating third instance from snapshot: %s" % snapshot['id'])
volume = self._create_volume_from_snapshot(snapshot['id'])
server_from_snapshot = (
self._boot_instance_from_volume(volume['id'],
keypair, security_group))
# check the content of written file
+ LOG.info("Logging into third instance to get timestamp: %s" %
+ server_from_snapshot)
server_from_snapshot_ip = self.get_server_ip(server_from_snapshot)
timestamp3 = self.get_timestamp(server_from_snapshot_ip,
private_key=keypair['private_key'])
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
index d8cb99d..6e24801 100644
--- a/tempest/services/baremetal/base.py
+++ b/tempest/services/baremetal/base.py
@@ -16,7 +16,7 @@
import six
from six.moves.urllib import parse as urllib
-from tempest.common import service_client
+from tempest.lib.common import rest_client
def handle_errors(f):
@@ -39,7 +39,7 @@
return wrapper
-class BaremetalClient(service_client.ServiceClient):
+class BaremetalClient(rest_client.RestClient):
"""Base Tempest REST client for Ironic API."""
uri_prefix = ''
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index ec9b1e0..045f03c 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -17,7 +17,7 @@
from tempest.api_schema.response.compute.v2_1 import keypairs as schemav21
from tempest.api_schema.response.compute.v2_2 import keypairs as schemav22
-from tempest.common import service_client
+from tempest.lib.common import rest_client
from tempest.services.compute.json import base_compute_client
@@ -31,14 +31,14 @@
body = json.loads(body)
schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.list_keypairs, resp, body)
- return service_client.ResponseBody(resp, body)
+ return rest_client.ResponseBody(resp, body)
def show_keypair(self, keypair_name):
resp, body = self.get("os-keypairs/%s" % keypair_name)
body = json.loads(body)
schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.get_keypair, resp, body)
- return service_client.ResponseBody(resp, body)
+ return rest_client.ResponseBody(resp, body)
def create_keypair(self, **kwargs):
post_body = json.dumps({'keypair': kwargs})
@@ -46,10 +46,10 @@
body = json.loads(body)
schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.create_keypair, resp, body)
- return service_client.ResponseBody(resp, body)
+ return rest_client.ResponseBody(resp, body)
def delete_keypair(self, keypair_name):
resp, body = self.delete("os-keypairs/%s" % keypair_name)
schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.delete_keypair, resp, body)
- return service_client.ResponseBody(resp, body)
+ return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/data_processing/v1_1/data_processing_client.py b/tempest/services/data_processing/v1_1/data_processing_client.py
index 5aa2622..c74672f 100644
--- a/tempest/services/data_processing/v1_1/data_processing_client.py
+++ b/tempest/services/data_processing/v1_1/data_processing_client.py
@@ -14,10 +14,10 @@
from oslo_serialization import jsonutils as json
-from tempest.common import service_client
+from tempest.lib.common import rest_client
-class DataProcessingClient(service_client.ServiceClient):
+class DataProcessingClient(rest_client.RestClient):
def _request_and_check_resp(self, request_func, uri, resp_status):
"""Make a request and check response status code.
@@ -26,7 +26,7 @@
"""
resp, body = request_func(uri)
self.expected_success(resp_status, resp.status)
- return service_client.ResponseBody(resp, body)
+ return rest_client.ResponseBody(resp, body)
def _request_and_check_resp_data(self, request_func, uri, resp_status):
"""Make a request and check response status code.
@@ -47,7 +47,7 @@
resp, body = request_func(uri, headers=headers, *args, **kwargs)
self.expected_success(resp_status, resp.status)
body = json.loads(body)
- return service_client.ResponseBody(resp, body)
+ return rest_client.ResponseBody(resp, body)
def list_node_group_templates(self):
"""List all node group templates for a user."""
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index fed33c5..28c3cfd 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -18,7 +18,7 @@
from tempest.common import service_client
-class IdentityV3Client(service_client.ServiceClient):
+class IdentityClient(service_client.ServiceClient):
api_version = "v3"
def show_api_description(self):
diff --git a/tempest/services/identity/v3/json/users_clients.py b/tempest/services/identity/v3/json/users_clients.py
index 85c2e79..481fdf0 100644
--- a/tempest/services/identity/v3/json/users_clients.py
+++ b/tempest/services/identity/v3/json/users_clients.py
@@ -18,7 +18,7 @@
from tempest.common import service_client
-class UsersV3Client(service_client.ServiceClient):
+class UsersClient(service_client.ServiceClient):
api_version = "v3"
def create_user(self, user_name, password=None, project_id=None,
diff --git a/tempest/test.py b/tempest/test.py
index 35a1944..fe3c770 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -249,6 +249,9 @@
# Client manager class to use in this test case.
client_manager = clients.Manager
+ # A way to adjust slow test classes
+ TIMEOUT_SCALING_FACTOR = 1
+
@classmethod
def setUpClass(cls):
# It should never be overridden by descendants
@@ -419,7 +422,7 @@
at_exit_set.add(self.__class__)
test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0)
try:
- test_timeout = int(test_timeout)
+ test_timeout = int(test_timeout) * self.TIMEOUT_SCALING_FACTOR
except ValueError:
test_timeout = 0
if test_timeout > 0:
diff --git a/tempest/tests/common/test_service_clients.py b/tempest/tests/common/test_service_clients.py
index 7e9ff9d..0c58e71 100644
--- a/tempest/tests/common/test_service_clients.py
+++ b/tempest/tests/common/test_service_clients.py
@@ -16,8 +16,6 @@
import random
import six
-from tempest.services.baremetal.v1.json import baremetal_client
-from tempest.services.data_processing.v1_1 import data_processing_client
from tempest.services.database.json import flavors_client as db_flavor_client
from tempest.services.database.json import versions_client as db_version_client
from tempest.services.identity.v2.json import identity_client as \
@@ -81,8 +79,6 @@
@mock.patch('tempest.lib.common.rest_client.RestClient.__init__')
def test_service_client_creations_with_specified_args(self, mock_init):
test_clients = [
- baremetal_client.BaremetalClient,
- data_processing_client.DataProcessingClient,
db_flavor_client.DatabaseFlavorsClient,
db_version_client.DatabaseVersionsClient,
network_client.NetworkClient,
@@ -115,7 +111,7 @@
identity_v2_identity_client.IdentityClient,
credentials_client.CredentialsClient,
endpoints_client.EndPointClient,
- identity_v3_identity_client.IdentityV3Client,
+ identity_v3_identity_client.IdentityClient,
policies_client.PoliciesClient,
regions_client.RegionsClient,
services_client.ServicesClient,
diff --git a/tempest/tests/lib/fake_auth_provider.py b/tempest/tests/lib/fake_auth_provider.py
index 7f00fb8..8095453 100644
--- a/tempest/tests/lib/fake_auth_provider.py
+++ b/tempest/tests/lib/fake_auth_provider.py
@@ -16,15 +16,16 @@
class FakeAuthProvider(object):
- def __init__(self, creds_dict=None):
+ def __init__(self, creds_dict=None, fake_base_url=None):
creds_dict = creds_dict or {}
self.credentials = FakeCredentials(creds_dict)
+ self.fake_base_url = fake_base_url
def auth_request(self, method, url, headers=None, body=None, filters=None):
return url, headers, body
def base_url(self, filters, auth_data=None):
- return "https://example.com"
+ return self.fake_base_url or "https://example.com"
class FakeCredentials(object):
diff --git a/tempest/tests/lib/services/compute/test_versions_client.py b/tempest/tests/lib/services/compute/test_versions_client.py
index 5ac2f2d..fc6c1d2 100644
--- a/tempest/tests/lib/services/compute/test_versions_client.py
+++ b/tempest/tests/lib/services/compute/test_versions_client.py
@@ -94,3 +94,42 @@
def test_get_version_by_url_with_bytes_body(self):
self._test_get_version_by_url(bytes_body=True)
+
+ def _test_get_base_version_url(self, url, expected_base_url):
+ auth = fake_auth_provider.FakeAuthProvider(fake_base_url=url)
+ client = versions_client.VersionsClient(auth, 'compute', 'regionOne')
+ self.assertEqual(expected_base_url, client._get_base_version_url())
+
+ def test_get_base_version_url(self):
+ self._test_get_base_version_url('https://bar.org/v2/123',
+ 'https://bar.org/')
+ self._test_get_base_version_url('https://bar.org/v2.1/123',
+ 'https://bar.org/')
+ self._test_get_base_version_url('https://bar.org/v2.15/123',
+ 'https://bar.org/')
+ self._test_get_base_version_url('https://bar.org/v22.2/123',
+ 'https://bar.org/')
+ self._test_get_base_version_url('https://bar.org/v22/123',
+ 'https://bar.org/')
+
+ def test_get_base_version_url_app_name(self):
+ self._test_get_base_version_url('https://bar.org/compute/v2/123',
+ 'https://bar.org/compute/')
+ self._test_get_base_version_url('https://bar.org/compute/v2.1/123',
+ 'https://bar.org/compute/')
+ self._test_get_base_version_url('https://bar.org/compute/v2.15/123',
+ 'https://bar.org/compute/')
+ self._test_get_base_version_url('https://bar.org/compute/v22.2/123',
+ 'https://bar.org/compute/')
+ self._test_get_base_version_url('https://bar.org/compute/v22/123',
+ 'https://bar.org/compute/')
+
+ def test_get_base_version_url_double_slash(self):
+ self._test_get_base_version_url('https://bar.org//v2/123',
+ 'https://bar.org/')
+ self._test_get_base_version_url('https://bar.org//v2.1/123',
+ 'https://bar.org/')
+ self._test_get_base_version_url('https://bar.org/compute//v2/123',
+ 'https://bar.org/compute/')
+ self._test_get_base_version_url('https://bar.org/compute//v2.1/123',
+ 'https://bar.org/compute/')