Merge "change ipv6 format to pass on postgresql"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 3cbe1b5..8429cd0 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -7,18 +7,11 @@
# custom Keystone service catalog implementation, you probably want to leave
# this value as "identity"
catalog_type = identity
-# Set to True if your test environment's Keystone authentication service should
-# be accessed over HTTPS
-use_ssl = False
-# This is the main host address of the authentication service API
-host = 127.0.0.1
-# Port that the authentication service API is running on
-port = 5000
-# Version of the authentication service API (a string)
-api_version = v2.0
-# Path to the authentication service tokens resource (do not modify unless you
-# have a custom authentication API and are not using Keystone)
-path = tokens
+# Ignore SSL certificate validation failures? Use when in testing
+# environments that have self-signed SSL certs.
+disable_ssl_certificate_validation = False
+# URL for where to find the OpenStack Identity API endpoint (Keystone)
+uri = http://127.0.0.1:5000/v2.0/
# Should typically be left as keystone unless you have a non-Keystone
# authentication API service
strategy = keystone
diff --git a/stress/tools/nova_destroy_all.py b/stress/tools/nova_destroy_all.py
index 21cac11..0070e72 100755
--- a/stress/tools/nova_destroy_all.py
+++ b/stress/tools/nova_destroy_all.py
@@ -24,7 +24,7 @@
compute = tempest.config.TempestConfig().compute
nt = client.Client(compute.username, compute.password,
- compute.tenant_name, identity.auth_url)
+ compute.tenant_name, identity.uri)
flavor_list = nt.flavors.list()
server_list = nt.servers.list()
diff --git a/stress/tools/nova_status.py b/stress/tools/nova_status.py
index d413d7a..f9bc707 100755
--- a/stress/tools/nova_status.py
+++ b/stress/tools/nova_status.py
@@ -23,10 +23,10 @@
identity = tempest.config.TempestConfig().identity
compute = tempest.config.TempestConfig().compute
print compute.username, compute.password,\
- compute.tenant_name, identity.auth_url
+ compute.tenant_name, identity.uri
nt = client.Client(compute.username, compute.password,
- compute.tenant_name, identity.auth_url)
+ compute.tenant_name, identity.uri)
flavor_list = nt.flavors.list()
server_list = nt.servers.list()
diff --git a/tempest/clients.py b/tempest/clients.py
index 0bb1752..ac163b6 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -64,6 +64,8 @@
from tempest.services.volume.xml.volumes_client import VolumesClientXML
from tempest.services.object_storage.object_client import \
ObjectClientCustomizedHeader
+from tempest.services.object_storage.account_client import \
+ AccountClientCustomizedHeader
LOG = logging.getLogger(__name__)
@@ -164,7 +166,7 @@
"tenant_name: %(tenant_name)s") % locals()
raise exceptions.InvalidConfiguration(msg)
- self.auth_url = self.config.identity.auth_url
+ self.auth_url = self.config.identity.uri
if self.config.identity.strategy == 'keystone':
client_args = (self.config, self.username, self.password,
@@ -202,6 +204,8 @@
self.ec2api_client = APIClientEC2(*client_args)
self.s3_client = ObjectClientS3(*client_args)
self.custom_object_client = ObjectClientCustomizedHeader(*client_args)
+ self.custom_account_client = \
+ AccountClientCustomizedHeader(*client_args)
class AltManager(Manager):
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 287ef56..4213b10 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -103,7 +103,8 @@
params['headers'] = {'User-Agent': 'Test-Client', 'X-Auth-User': user,
'X-Auth-Key': password}
- self.http_obj = httplib2.Http(disable_ssl_certificate_validation=True)
+ dscv = self.config.identity.disable_ssl_certificate_validation
+ self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
resp, body = self.http_obj.request(auth_url, 'GET', **params)
try:
return resp['x-auth-token'], resp['x-server-management-url']
@@ -115,6 +116,10 @@
Provides authentication via Keystone
"""
+ # Normalize URI to ensure /tokens is in it.
+ if 'tokens' not in auth_url:
+ auth_url = auth_url.rstrip('/') + '/tokens'
+
creds = {
'auth': {
'passwordCredentials': {
@@ -125,7 +130,8 @@
}
}
- self.http_obj = httplib2.Http(disable_ssl_certificate_validation=True)
+ dscv = self.config.identity.disable_ssl_certificate_validation
+ self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
headers = {'Content-Type': 'application/json'}
body = json.dumps(creds)
resp, body = self.http_obj.request(auth_url, 'POST',
@@ -200,7 +206,8 @@
if (self.token is None) or (self.base_url is None):
self._set_auth()
- self.http_obj = httplib2.Http(disable_ssl_certificate_validation=True)
+ dscv = self.config.identity.disable_ssl_certificate_validation
+ self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
if headers is None:
headers = {}
headers['X-Auth-Token'] = self.token
diff --git a/tempest/common/utils/data_utils.py b/tempest/common/utils/data_utils.py
index 3a7661c..7c6a58b 100644
--- a/tempest/common/utils/data_utils.py
+++ b/tempest/common/utils/data_utils.py
@@ -60,7 +60,7 @@
def parse_image_id(image_ref):
"""Return the image id from a given image ref."""
- return image_ref.rsplit('/')[-1]
+ return image_ref.rsplit('/')[-1]
def arbitrary_string(size=4, base_text=None):
diff --git a/tempest/config.py b/tempest/config.py
index 8233dd5..70b1c79 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -31,21 +31,28 @@
cfg.StrOpt('catalog_type',
default='identity',
help="Catalog type of the Identity service."),
+ cfg.BoolOpt('disable_ssl_certificate_validation',
+ default=False,
+ help="Set to True if using self-signed SSL certificates."),
+ cfg.StrOpt('uri',
+ default=None,
+ help="Full URI of the OpenStack Identity API (Keystone)"),
cfg.StrOpt('host',
default="127.0.0.1",
- help="Host IP for making Identity API requests."),
+ help="(DEPRECATED, use uri) Host IP for making Identity "
+ "API requests."),
cfg.IntOpt('port',
default=8773,
- help="Port for the Identity service."),
+ help="(DEPRECATED, use uri) Port for the Identity service."),
cfg.StrOpt('api_version',
default="v1.1",
- help="Version of the Identity API"),
+ help="(DEPRECATED, use uri) Version of the Identity API"),
cfg.StrOpt('path',
default='/',
- help="Path of API request"),
+ help="(IGNORED) Path of API request"),
cfg.BoolOpt('use_ssl',
default=False,
- help="Specifies if we are using https."),
+ help="(DEPRECATED, use uri) Specifies if we are using https."),
cfg.StrOpt('strategy',
default='keystone',
help="Which auth method does the environment use? "
@@ -61,16 +68,15 @@
for opt in IdentityGroup:
conf.register_opt(opt, group='identity')
+ # Fall back to piecemeal identity URI for legacy support
authurl = data_utils.build_url(conf.identity.host,
str(conf.identity.port),
conf.identity.api_version,
- conf.identity.path,
+ path='', # Ignore path...
use_ssl=conf.identity.use_ssl)
- auth_url = cfg.StrOpt('auth_url',
- default=authurl,
- help="The Identity URL (derived)")
- conf.register_opt(auth_url, group="identity")
+ if not conf.identity.uri:
+ conf.identity.uri = authurl
identity_admin_group = cfg.OptGroup(name='identity-admin',
diff --git a/tempest/manager.py b/tempest/manager.py
index 513e5d9..8e7cbd1 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -126,8 +126,8 @@
"tenant_name: %(tenant_name)s") % locals()
raise exceptions.InvalidConfiguration(msg)
- # Novaclient adds a /tokens/ part to the auth URL automatically
- auth_url = self.config.identity.auth_url.rstrip('tokens')
+ auth_url = self.config.identity.uri
+ dscv = self.config.identity.disable_ssl_certificate_validation
client_args = (username, password, tenant_name, auth_url)
@@ -136,14 +136,17 @@
return novaclient.client.Client(self.NOVACLIENT_VERSION,
*client_args,
service_type=service_type,
- no_cache=True)
+ no_cache=True,
+ insecure=dscv)
def _get_image_client(self):
keystone = self._get_identity_client()
token = keystone.auth_token
endpoint = keystone.service_catalog.url_for(service_type='image',
endpoint_type='publicURL')
- return glanceclient.Client('1', endpoint=endpoint, token=token)
+ dscv = self.config.identity.disable_ssl_certificate_validation
+ return glanceclient.Client('1', endpoint=endpoint, token=token,
+ insecure=dscv)
def _get_identity_client(self, username=None, password=None,
tenant_name=None):
@@ -162,12 +165,14 @@
"tenant_name: %(tenant_name)s") % locals()
raise exceptions.InvalidConfiguration(msg)
- auth_url = self.config.identity.auth_url.rstrip('tokens')
+ auth_url = self.config.identity.uri
+ dscv = self.config.identity.disable_ssl_certificate_validation
return keystoneclient.v2_0.client.Client(username=username,
password=password,
tenant_name=tenant_name,
- auth_url=auth_url)
+ auth_url=auth_url,
+ insecure=dscv)
def _get_network_client(self):
# The intended configuration is for the network client to have
@@ -186,12 +191,14 @@
"tenant_name: %(tenant_name)s") % locals()
raise exceptions.InvalidConfiguration(msg)
- auth_url = self.config.identity.auth_url.rstrip('tokens')
+ auth_url = self.config.identity.uri
+ dscv = self.config.identity.disable_ssl_certificate_validation
return quantumclient.v2_0.client.Client(username=username,
password=password,
tenant_name=tenant_name,
- auth_url=auth_url)
+ auth_url=auth_url,
+ insecure=dscv)
class ComputeFuzzClientManager(FuzzClientManager):
@@ -225,7 +232,11 @@
"tenant_name: %(tenant_name)s") % locals()
raise exceptions.InvalidConfiguration(msg)
- auth_url = self.config.identity.auth_url
+ auth_url = self.config.identity.uri
+
+ # Ensure /tokens is in the URL for Keystone...
+ if 'tokens' not in auth_url:
+ auth_url = auth_url.rstrip('/') + '/tokens'
if self.config.identity.strategy == 'keystone':
client_args = (self.config, username, password, auth_url,
diff --git a/tempest/services/boto/__init__.py b/tempest/services/boto/__init__.py
index 1365435..f744d9d 100644
--- a/tempest/services/boto/__init__.py
+++ b/tempest/services/boto/__init__.py
@@ -38,10 +38,6 @@
self.connection_timeout = str(config.boto.http_socket_timeout)
self.num_retries = str(config.boto.num_retries)
self.build_timeout = config.boto.build_timeout
- # We do not need the "path": "/token" part
- if auth_url:
- auth_url = re.sub("(.*)" + re.escape(config.identity.path) + "$",
- "\\1", auth_url)
self.ks_cred = {"username": username,
"password": password,
"auth_url": auth_url,
@@ -100,4 +96,4 @@
else:
raise InvalidConfiguration(
"Unable to get access and secret keys")
- return self.connect_method(**self.connection_data)
+ return self.connect_method(**self.connection_data)
diff --git a/tempest/services/identity/json/admin_client.py b/tempest/services/identity/json/admin_client.py
index c4e6c95..7b1cb4b 100644
--- a/tempest/services/identity/json/admin_client.py
+++ b/tempest/services/identity/json/admin_client.py
@@ -206,7 +206,15 @@
class TokenClientJSON(RestClient):
def __init__(self, config):
- self.auth_url = config.identity.auth_url
+ auth_url = config.identity.uri
+
+ # TODO(jaypipes) Why is this all repeated code in here?
+ # Normalize URI to ensure /tokens is in it.
+ if 'tokens' not in auth_url:
+ auth_url = auth_url.rstrip('/') + '/tokens'
+
+ self.auth_url = auth_url
+ self.config = config
def auth(self, user, password, tenant):
creds = {
@@ -225,7 +233,8 @@
def request(self, method, url, headers=None, body=None):
"""A simple HTTP request interface."""
- self.http_obj = httplib2.Http()
+ dscv = self.config.identity.disable_ssl_certificate_validation
+ self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
if headers is None:
headers = {}
diff --git a/tempest/services/identity/xml/admin_client.py b/tempest/services/identity/xml/admin_client.py
index 60897e9..1c71d87 100644
--- a/tempest/services/identity/xml/admin_client.py
+++ b/tempest/services/identity/xml/admin_client.py
@@ -242,7 +242,15 @@
class TokenClientXML(RestClientXML):
def __init__(self, config):
- self.auth_url = config.identity.auth_url
+ auth_url = config.identity.uri
+
+ # TODO(jaypipes) Why is this all repeated code in here?
+ # Normalize URI to ensure /tokens is in it.
+ if 'tokens' not in auth_url:
+ auth_url = auth_url.rstrip('/') + '/tokens'
+
+ self.auth_url = auth_url
+ self.config = config
def auth(self, user, password, tenant):
passwordCreds = Element("passwordCredentials",
@@ -257,7 +265,8 @@
def request(self, method, url, headers=None, body=None):
"""A simple HTTP request interface."""
- self.http_obj = httplib2.Http()
+ dscv = self.config.identity.disable_ssl_certificate_validation
+ self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
if headers is None:
headers = {}
diff --git a/tempest/services/image/service.py b/tempest/services/image/service.py
index 154b5b8..cf4ff4d 100644
--- a/tempest/services/image/service.py
+++ b/tempest/services/image/service.py
@@ -41,12 +41,14 @@
import glanceclient
import keystoneclient.v2_0.client
- auth_url = self.config.identity.auth_url.rstrip('tokens')
+ dscv = self.config.identity.disable_ssl_certificate_validation
+ auth_url = self.config.identity.uri
keystone = keystoneclient.v2_0.client.Client(
username=config.images.username,
password=config.images.password,
tenant_name=config.images.tenant_name,
- auth_url=auth_url)
+ auth_url=auth_url,
+ insecure=dscv)
token = keystone.auth_token
endpoint = keystone.service_catalog.url_for(
service_type='image',
@@ -54,7 +56,8 @@
self._client = glanceclient.Client('1',
endpoint=endpoint,
- token=token)
+ token=token,
+ insecure=dscv)
else:
raise NotImplementedError
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index 26f8329..734307c 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -15,10 +15,12 @@
# License for the specific language governing permissions and limitations
# under the License.
+import httplib2
import json
import urllib
from tempest.common.rest_client import RestClient
+from tempest import exceptions
class AccountClient(RestClient):
@@ -89,3 +91,66 @@
resp, body = self.get(url)
body = json.loads(body)
return resp, body
+
+
+class AccountClientCustomizedHeader(RestClient):
+
+ def __init__(self, config, username, password, auth_url, tenant_name=None):
+ super(AccountClientCustomizedHeader, self).__init__(config, username,
+ password, auth_url,
+ tenant_name)
+ #Overwrites json-specific header encoding in RestClient
+ self.service = self.config.object_storage.catalog_type
+ self.format = 'json'
+
+ def request(self, method, url, headers=None, body=None, wait=None):
+ """A simple HTTP request interface."""
+ self.http_obj = httplib2.Http()
+ if headers is None:
+ headers = {}
+ if self.base_url is None:
+ self._set_auth()
+
+ req_url = "%s/%s" % (self.base_url, url)
+ resp, resp_body = self.http_obj.request(req_url, method,
+ headers=headers, body=body)
+
+ if resp.status == 401 or resp.status == 403:
+ self._log(req_url, body, resp, resp_body)
+ raise exceptions.Unauthorized()
+
+ return resp, resp_body
+
+ def list_account_containers(self, params=None, metadata=None):
+ """
+ GET on the (base) storage URL
+ Given the X-Storage-URL and a valid X-Auth-Token, returns
+ a list of all containers for the account.
+
+ Optional Arguments:
+ limit=[integer value N]
+ Limits the number of results to at most N values
+ DEFAULT: 10,000
+
+ marker=[string value X]
+ Given string value X, return object names greater in value
+ than the specified marker.
+ DEFAULT: No Marker
+
+ format=[string value, either 'json' or 'xml']
+ Specify either json or xml to return the respective serialized
+ response.
+ DEFAULT: Python-List returned in response body
+ """
+
+ url = '?format=%s' % self.format
+ if params:
+ url += '&%s' + urllib.urlencode(params)
+
+ headers = {}
+ if metadata:
+ for key in metadata:
+ headers[str(key)] = metadata[key]
+
+ resp, body = self.get(url, headers=headers)
+ return resp, body
diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py
index c05c905..2256170 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/services/object_storage/object_client.py
@@ -15,11 +15,14 @@
# License for the specific language governing permissions and limitations
# under the License.
+from hashlib import sha1
+import hmac
import httplib2
import json
import re
from tempest.common.rest_client import RestClient
from tempest import exceptions
+from urlparse import urlparse
class ObjectClient(RestClient):
@@ -120,6 +123,23 @@
resp, body = self.copy(url, headers=headers)
return resp, body
+ def get_object_using_temp_url(self, container, object_name, expires, key):
+ """Retrieve object's data using temp URL."""
+
+ self._set_auth()
+ method = 'GET'
+ path = "%s/%s/%s" % (urlparse(self.base_url).path, container,
+ object_name)
+ hmac_body = '%s\n%s\n%s' % (method, expires, path)
+ sig = hmac.new(key, hmac_body, sha1).hexdigest()
+
+ url = "%s/%s?temp_url_sig=%s&temp_url_expires=%s" % (container,
+ object_name,
+ sig, expires)
+
+ resp, body = self.get(url)
+ return resp, body
+
class ObjectClientCustomizedHeader(RestClient):
@@ -133,7 +153,8 @@
def request(self, method, url, headers=None, body=None, wait=None):
"""A simple HTTP request interface."""
- self.http_obj = httplib2.Http()
+ dscv = self.config.identity.disable_ssl_certificate_validation
+ self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
if headers is None:
headers = {}
if self.base_url is None:
@@ -172,9 +193,14 @@
resp, body = self.put(url, data, headers=headers)
return resp, body
- def delete_object(self, container, object_name):
+ def delete_object(self, container, object_name, metadata=None):
"""Delete storage object."""
+ headers = {}
+ if metadata:
+ for key in metadata:
+ headers[str(key)] = metadata[key]
+
url = "%s/%s" % (str(container), str(object_name))
- resp, body = self.delete(url)
+ resp, body = self.delete(url, headers=headers)
return resp, body
diff --git a/tempest/testboto.py b/tempest/testboto.py
index c38bf99..09ac950 100644
--- a/tempest/testboto.py
+++ b/tempest/testboto.py
@@ -22,6 +22,7 @@
import boto
from boto.exception import BotoServerError
+from boto.exception import EC2ResponseError
from boto.s3.bucket import Bucket
from boto.s3.key import Key
import nose
@@ -203,26 +204,32 @@
'deleting', 'deleted', 'error'))
valid_snapshot_status = set(('pending', 'completed', 'error'))
- #TODO(afazekas): object base version for resurces supports update
- def waitImageState(self, lfunction, wait_for):
- state = state_wait(lfunction, wait_for, self.valid_image_state)
- self.assertIn(state, self.valid_image_state)
+ gone_set = set(('_GONE',))
+
+ def state_wait_gone(self, lfunction, final_set, valid_set):
+ if not isinstance(final_set, set):
+ final_set = set((final_set,))
+ final_set |= self.gone_set
+ state = state_wait(lfunction, final_set, valid_set)
+ self.assertIn(state, valid_set | self.gone_set)
return state
+ #TODO(afazekas): object based versions for resurces which supports update
+ def waitImageState(self, lfunction, wait_for):
+ return self.state_wait_gone(lfunction, wait_for,
+ self.valid_image_state)
+
def waitInstanceState(self, lfunction, wait_for):
- state = state_wait(lfunction, wait_for, self.valid_instance_state)
- self.assertIn(state, self.valid_instance_state)
- return state
+ return self.state_wait_gone(lfunction, wait_for,
+ self.valid_instance_state)
def waitVolumeStatus(self, lfunction, wait_for):
- state = state_wait(lfunction, wait_for, self.valid_volume_status)
- self.assertIn(state, self.valid_volume_status)
- return state
+ return self.state_wait_gone(lfunction, wait_for,
+ self.valid_volume_status)
def waitSnapshotStatus(self, lfunction, wait_for):
- state = state_wait(lfunction, wait_for, self.valid_snapshot_status)
- self.assertIn(state, self.valid_snapshot_status)
- return state
+ return self.state_wait_gone(lfunction, wait_for,
+ self.valid_snapshot_status)
def assertImageStateWait(self, lfunction, wait_for):
state = self.waitImageState(lfunction, wait_for)
@@ -323,13 +330,22 @@
try:
instance.update(validate=True)
except ValueError:
- return "terminated"
+ return "_GONE"
+ except EC2ResponseError as exc:
+ if cls.ec2_error_code.\
+ client.InvalidInstanceID.NotFound.match(exc):
+ return "_GONE"
+ #NOTE(afazekas): incorrect code,
+ # but the resource must be destoreyd
+ if exc.error_code == "InstanceNotFound":
+ return "_GONE"
+
return instance.state
for instance in reservation.instances:
try:
instance.terminate()
- re_search_wait(_instance_state, "terminated")
+ re_search_wait(_instance_state, "_GONE")
except BaseException as exc:
LOG.exception(exc)
exc_num += 1
@@ -345,8 +361,6 @@
Use just for teardown!
"""
#NOTE(afazekas): should wait/try until all related instance terminates
- #2. looks like it is locked even if the instance not listed
- time.sleep(1)
group.delete()
@classmethod
diff --git a/tempest/tests/boto/__init__.py b/tempest/tests/boto/__init__.py
index 62918c2..ec51b18 100644
--- a/tempest/tests/boto/__init__.py
+++ b/tempest/tests/boto/__init__.py
@@ -85,7 +85,7 @@
s3client = openstack.s3_client
try:
s3client.get_bucket("^INVALID*#()@INVALID.")
- except boto.exception.BotoServerError as exc:
+ except boto.exception.BotoServerError as exc:
if exc.status == 403:
_cred_sub_check(s3client.connection_data)
except Exception as exc:
diff --git a/tempest/tests/boto/test_ec2_instance_run.py b/tempest/tests/boto/test_ec2_instance_run.py
index 331e54c..6a8778a 100644
--- a/tempest/tests/boto/test_ec2_instance_run.py
+++ b/tempest/tests/boto/test_ec2_instance_run.py
@@ -18,6 +18,7 @@
from contextlib import closing
import logging
+from boto.exception import EC2ResponseError
from boto.s3.key import Key
import nose
from nose.plugins.attrib import attr
@@ -121,7 +122,7 @@
self.cancelResourceCleanUp(rcuk)
@attr(type='smoke')
- @unittest.skip("Skipped until the Bug #1098112 is resolved")
+ @unittest.skip("Skipped until the Bug #1098891 is resolved")
def test_run_terminate_instance(self):
# EC2 run, terminate immediately
image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -132,9 +133,18 @@
for instance in reservation.instances:
instance.terminate()
-
- instance.update(validate=True)
- self.assertNotEqual(instance.state, "running")
+ try:
+ instance.update(validate=True)
+ except ValueError:
+ pass
+ except EC2ResponseError as exc:
+ if self.ec2_error_code.\
+ client.InvalidInstanceID.NotFound.match(exc):
+ pass
+ else:
+ raise
+ else:
+ self.assertNotEqual(instance.state, "running")
#NOTE(afazekas): doctored test case,
# with normal validation it would fail
diff --git a/tempest/tests/compute/__init__.py b/tempest/tests/compute/__init__.py
index 0258708..190cb5f 100644
--- a/tempest/tests/compute/__init__.py
+++ b/tempest/tests/compute/__init__.py
@@ -21,6 +21,7 @@
from tempest import clients
from tempest import config
+from tempest.exceptions import InvalidConfiguration
LOG = logging.getLogger(__name__)
@@ -51,19 +52,15 @@
# Validate reference data exists
# If not, we raise the exception here and prevent
# going forward...
- try:
- image_ref = CONFIG.compute.image_ref
- image_ref_alt = CONFIG.compute.image_ref_alt
- images_client.get_image(image_ref)
- images_client.get_image(image_ref_alt)
+ image_ref = CONFIG.compute.image_ref
+ image_ref_alt = CONFIG.compute.image_ref_alt
+ images_client.get_image(image_ref)
+ images_client.get_image(image_ref_alt)
- flavor_ref = CONFIG.compute.flavor_ref
- flavor_ref_alt = CONFIG.compute.flavor_ref_alt
- flavors_client.get_flavor_details(flavor_ref)
- flavors_client.get_flavor_details(flavor_ref_alt)
- except Exception as e:
- msg = "Failed basic configuration: %s" % e
- raise nose.SkipTest(msg)
+ flavor_ref = CONFIG.compute.flavor_ref
+ flavor_ref_alt = CONFIG.compute.flavor_ref_alt
+ flavors_client.get_flavor_details(flavor_ref)
+ flavors_client.get_flavor_details(flavor_ref_alt)
# Determine if there are two regular users that can be
# used in testing. If the test cases are allowed to create
@@ -79,6 +76,7 @@
user2_tenant_name = CONFIG.compute.alt_tenant_name
if not user2_password or not user2_tenant_name:
msg = ("Alternate user specified but not alternate "
- "tenant or password")
- raise nose.SkipTest(msg)
+ "tenant or password: alt_tenant_name=%s alt_password=%s"
+ % (user2_tenant_name, user2_password))
+ raise InvalidConfiguration(msg)
MULTI_USER = True
diff --git a/tempest/tests/compute/admin/test_quotas.py b/tempest/tests/compute/admin/test_quotas.py
index 452de80..eaf245a 100644
--- a/tempest/tests/compute/admin/test_quotas.py
+++ b/tempest/tests/compute/admin/test_quotas.py
@@ -30,7 +30,7 @@
adm_user = cls.config.compute_admin.username
adm_pass = cls.config.compute_admin.password
adm_tenant = cls.config.compute_admin.tenant_name
- auth_url = cls.config.identity.auth_url
+ auth_url = cls.config.identity.uri
cls.adm_client = adm_quotas.AdminQuotasClient(cls.config, adm_user,
adm_pass, auth_url,
diff --git a/tempest/tests/compute/base.py b/tempest/tests/compute/base.py
index 8044d01..c44a2f1 100644
--- a/tempest/tests/compute/base.py
+++ b/tempest/tests/compute/base.py
@@ -89,7 +89,7 @@
cls.config,
cls.config.identity_admin.username,
cls.config.identity_admin.password,
- cls.config.identity.auth_url
+ cls.config.identity.uri
)
@classmethod
diff --git a/tempest/tests/compute/images/test_images.py b/tempest/tests/compute/images/test_images.py
index 95678a2..2557f16 100644
--- a/tempest/tests/compute/images/test_images.py
+++ b/tempest/tests/compute/images/test_images.py
@@ -42,40 +42,6 @@
self.client.delete_image(image_id)
self.image_ids.remove(image_id)
- @attr(type='smoke')
- @unittest.skipUnless(compute.CREATE_IMAGE_ENABLED,
- 'Environment unable to create images.')
- def test_create_delete_image(self):
- # An image for the provided server should be created
- server_name = rand_name('server')
- resp, server = self.servers_client.create_server(server_name,
- self.image_ref,
- self.flavor_ref)
- self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
-
- # Create a new image
- name = rand_name('image')
- meta = {'image_type': 'test'}
- resp, body = self.client.create_image(server['id'], name, meta)
- self.assertEqual(202, resp.status)
- image_id = parse_image_id(resp['location'])
- self.client.wait_for_image_resp_code(image_id, 200)
- self.client.wait_for_image_status(image_id, 'ACTIVE')
-
- # Verify the image was created correctly
- resp, image = self.client.get_image(image_id)
- self.assertEqual(name, image['name'])
- self.assertEqual('test', image['metadata']['image_type'])
-
- # Verify minRAM and minDisk values are the same as the original image
- resp, original_image = self.client.get_image(self.image_ref)
- self.assertEqual(original_image['minRam'], image['minRam'])
- self.assertEqual(original_image['minDisk'], image['minDisk'])
-
- # Teardown
- self.client.delete_image(image['id'])
- self.servers_client.delete_server(server['id'])
-
@attr(type='negative')
def test_create_image_from_deleted_server(self):
# An image should not be created if the server instance is removed
@@ -126,13 +92,13 @@
"with invalid server id")
@attr(type='negative')
- @unittest.skipUnless(compute.MULTI_USER, 'Second user not configured')
- def test_create_image_for_server_in_another_tenant(self):
- # Creating image of another tenant's server should be return error
+ def test_create_image_when_server_is_terminating(self):
+ # Return an error when creating image of server that is terminating
server = self.create_server()
+ self.servers_client.delete_server(server['id'])
snapshot_name = rand_name('test-snap-')
- self.assertRaises(exceptions.NotFound, self.alt_client.create_image,
+ self.assertRaises(exceptions.Duplicate, self.client.create_image,
server['id'], snapshot_name)
@attr(type='negative')
@@ -159,52 +125,6 @@
server['id'], snapshot_name)
@attr(type='negative')
- def test_create_image_when_server_is_terminating(self):
- # Return an error when creating image of server that is terminating
- server = self.create_server()
- self.servers_client.delete_server(server['id'])
-
- snapshot_name = rand_name('test-snap-')
- self.assertRaises(exceptions.Duplicate, self.client.create_image,
- server['id'], snapshot_name)
-
- @attr(type='negative')
- def test_create_second_image_when_first_image_is_being_saved(self):
- # Disallow creating another image when first image is being saved
- server = self.create_server()
-
- try:
- # Create first snapshot
- snapshot_name = rand_name('test-snap-')
- resp, body = self.client.create_image(server['id'], snapshot_name)
- image_id = parse_image_id(resp['location'])
- self.image_ids.append(image_id)
-
- # Create second snapshot
- alt_snapshot_name = rand_name('test-snap-')
- self.client.create_image(server['id'], alt_snapshot_name)
- except exceptions.Duplicate:
- pass
-
- else:
- self.fail("Should allow creating an image when another image of"
- "the server is still being saved")
-
- @attr(type='negative')
- @unittest.skip("Until Bug 1004564 is fixed")
- def test_create_image_specify_name_over_256_chars(self):
- # Return an error if snapshot name over 256 characters is passed
- server = self.create_server()
-
- try:
- snapshot_name = rand_name('a' * 260)
- self.assertRaises(exceptions.BadRequest, self.client.create_image,
- server['id'], snapshot_name)
- except Exception:
- self.fail("Should return 400 Bad Request if image name is over 256"
- " characters")
-
- @attr(type='negative')
def test_create_image_specify_uuid_35_characters_or_less(self):
# Return an error if Image ID passed is 35 characters or less
try:
@@ -229,51 +149,6 @@
" characters or more")
@attr(type='negative')
- @unittest.skip("Until Bug 1006725 is fixed")
- def test_create_image_specify_multibyte_character_image_name(self):
- # Return an error if the image name has multi-byte characters
- server = self.create_server()
-
- try:
- snapshot_name = rand_name('\xef\xbb\xbf')
- self.assertRaises(exceptions.BadRequest,
- self.client.create_image, server['id'],
- snapshot_name)
- except Exception:
- self.fail("Should return 400 Bad Request if multi byte characters"
- " are used for image name")
-
- @attr(type='negative')
- @unittest.skip("Until Bug 1005423 is fixed")
- def test_create_image_specify_invalid_metadata(self):
- # Return an error when creating image with invalid metadata
- server = self.create_server()
-
- try:
- snapshot_name = rand_name('test-snap-')
- meta = {'': ''}
- self.assertRaises(exceptions.BadRequest, self.client.create_image,
- server['id'], snapshot_name, meta)
-
- except Exception:
- self.fail("Should raise 400 Bad Request if meta data is invalid")
-
- @attr(type='negative')
- @unittest.skip("Until Bug 1005423 is fixed")
- def test_create_image_specify_metadata_over_limits(self):
- # Return an error when creating image with meta data over 256 chars
- server = self.create_server()
-
- try:
- snapshot_name = rand_name('test-snap-')
- meta = {'a' * 260: 'b' * 260}
- self.assertRaises(exceptions.OverLimit, self.client.create_image,
- server['id'], snapshot_name, meta)
-
- except Exception:
- self.fail("Should raise 413 Over Limit if meta data was too long")
-
- @attr(type='negative')
def test_delete_image_with_invalid_image_id(self):
# An image should not be deleted with invalid image id
try:
@@ -337,42 +212,6 @@
self.fail("Did not return HTTP 404 NotFound for image id that "
"exceeds 35 character ID length limit")
- @attr(type='negative')
- @unittest.skipUnless(compute.MULTI_USER, 'Second user not configured')
- def test_delete_image_of_another_tenant(self):
- # Return an error while trying to delete another tenant's image
-
- server = self.create_server()
-
- snapshot_name = rand_name('test-snap-')
- resp, body = self.client.create_image(server['id'], snapshot_name)
- image_id = parse_image_id(resp['location'])
- self.image_ids.append(image_id)
- self.client.wait_for_image_resp_code(image_id, 200)
- self.client.wait_for_image_status(image_id, 'ACTIVE')
-
- # Delete image
- self.assertRaises(exceptions.NotFound,
- self.alt_client.delete_image, image_id)
-
- @attr(type='negative')
- def test_delete_image_that_is_not_yet_active(self):
- # Return an error while trying to delete an active that is creating
-
- server = self.create_server()
-
- snapshot_name = rand_name('test-snap-')
- resp, body = self.client.create_image(server['id'], snapshot_name)
- image_id = parse_image_id(resp['location'])
- self.image_ids.append(image_id)
-
- # Do not wait, attempt to delete the image, ensure it's successful
- resp, body = self.client.delete_image(image_id)
- self.assertEqual('204', resp['status'])
- self.image_ids.remove(image_id)
-
- self.assertRaises(exceptions.NotFound, self.client.get_image, image_id)
-
class ImagesTestJSON(base.BaseComputeTestJSON,
ImagesTestBase):
@@ -381,7 +220,6 @@
@classmethod
def setUpClass(cls):
- raise nose.SkipTest("Until Bug 1046870 is fixed")
super(ImagesTestJSON, cls).setUpClass()
cls.client = cls.images_client
cls.servers_client = cls.servers_client
@@ -408,7 +246,6 @@
@classmethod
def setUpClass(cls):
- raise nose.SkipTest("Until Bug 1046870 is fixed")
super(ImagesTestXML, cls).setUpClass()
cls.client = cls.images_client
cls.servers_client = cls.servers_client
diff --git a/tempest/tests/compute/images/test_images_oneserver.py b/tempest/tests/compute/images/test_images_oneserver.py
new file mode 100644
index 0000000..f8b560b
--- /dev/null
+++ b/tempest/tests/compute/images/test_images_oneserver.py
@@ -0,0 +1,243 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack, LLC
+# 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.
+
+import nose
+from nose.plugins.attrib import attr
+import unittest2 as unittest
+
+from tempest import clients
+from tempest.common.utils.data_utils import parse_image_id
+from tempest.common.utils.data_utils import rand_name
+import tempest.config
+from tempest import exceptions
+from tempest.tests import compute
+from tempest.tests.compute import base
+
+
+class ImagesOneServerTestBase(object):
+ def tearDownClass(cls):
+ """Terminate test instances created after a test is executed."""
+ resp, body = self.servers_client.delete_server(cls.server['id'])
+ if resp['status'] == '204':
+ self.servers.remove(server)
+ self.servers_client.wait_for_server_termination(cls.server['id'])
+
+ def tearDown(self):
+ """Terminate test instances created after a test is executed."""
+ for image_id in self.image_ids:
+ self.client.delete_image(image_id)
+ self.image_ids.remove(image_id)
+
+ @attr(type='negative')
+ @unittest.skip("Until Bug 1006725 is fixed")
+ def test_create_image_specify_multibyte_character_image_name(self):
+ # Return an error if the image name has multi-byte characters
+ try:
+ snapshot_name = rand_name('\xef\xbb\xbf')
+ self.assertRaises(exceptions.BadRequest,
+ self.client.create_image, self.server['id'],
+ snapshot_name)
+ except Exception:
+ self.fail("Should return 400 Bad Request if multi byte characters"
+ " are used for image name")
+
+ @attr(type='negative')
+ @unittest.skip("Until Bug 1005423 is fixed")
+ def test_create_image_specify_invalid_metadata(self):
+ # Return an error when creating image with invalid metadata
+ try:
+ snapshot_name = rand_name('test-snap-')
+ meta = {'': ''}
+ self.assertRaises(exceptions.BadRequest, self.client.create_image,
+ self.server['id'], snapshot_name, meta)
+
+ except Exception:
+ self.fail("Should raise 400 Bad Request if meta data is invalid")
+
+ @attr(type='negative')
+ @unittest.skip("Until Bug 1005423 is fixed")
+ def test_create_image_specify_metadata_over_limits(self):
+ # Return an error when creating image with meta data over 256 chars
+ try:
+ snapshot_name = rand_name('test-snap-')
+ meta = {'a' * 260: 'b' * 260}
+ self.assertRaises(exceptions.OverLimit, self.client.create_image,
+ self.server['id'], snapshot_name, meta)
+
+ except Exception:
+ self.fail("Should raise 413 Over Limit if meta data was too long")
+
+ @attr(type='negative')
+ @unittest.skipUnless(compute.MULTI_USER,
+ 'Need multiple users for this test.')
+ def test_delete_image_of_another_tenant(self):
+ # Return an error while trying to delete another tenant's image
+ self.servers_client.wait_for_server_status(self.server['id'], 'ACTIVE')
+ snapshot_name = rand_name('test-snap-')
+ resp, body = self.client.create_image(self.server['id'], snapshot_name)
+ image_id = parse_image_id(resp['location'])
+ self.image_ids.append(image_id)
+ self.client.wait_for_image_resp_code(image_id, 200)
+ self.client.wait_for_image_status(image_id, 'ACTIVE')
+
+ # Delete image
+ self.assertRaises(exceptions.NotFound,
+ self.alt_client.delete_image, image_id)
+
+ @attr(type='smoke')
+ @unittest.skipUnless(compute.CREATE_IMAGE_ENABLED,
+ 'Environment unable to create images.')
+ def test_create_delete_image(self):
+
+ # Create a new image
+ name = rand_name('image')
+ meta = {'image_type': 'test'}
+ resp, body = self.client.create_image(self.server['id'], name, meta)
+ self.assertEqual(202, resp.status)
+ image_id = parse_image_id(resp['location'])
+ self.client.wait_for_image_resp_code(image_id, 200)
+ self.client.wait_for_image_status(image_id, 'ACTIVE')
+
+ # Verify the image was created correctly
+ resp, image = self.client.get_image(image_id)
+ self.assertEqual(name, image['name'])
+ self.assertEqual('test', image['metadata']['image_type'])
+
+ # Verify minRAM and minDisk values are the same as the original image
+ resp, original_image = self.client.get_image(self.image_ref)
+ self.assertEqual(original_image['minRam'], image['minRam'])
+ self.assertEqual(original_image['minDisk'], image['minDisk'])
+
+ @attr(type='negative')
+ @unittest.skipUnless(compute.MULTI_USER,
+ 'Need multiple users for this test.')
+ def test_create_image_for_server_in_another_tenant(self):
+ # Creating image of another tenant's server should be return error
+
+ snapshot_name = rand_name('test-snap-')
+ self.assertRaises(exceptions.NotFound, self.alt_client.create_image,
+ self.server['id'], snapshot_name)
+
+ @attr(type='negative')
+ def test_create_second_image_when_first_image_is_being_saved(self):
+ # Disallow creating another image when first image is being saved
+
+ try:
+ # Create first snapshot
+ snapshot_name = rand_name('test-snap-')
+ resp, body = self.client.create_image(self.server['id'],
+ snapshot_name)
+ self.assertEqual(202, resp.status)
+ image_id = parse_image_id(resp['location'])
+ self.image_ids.append(image_id)
+
+ # Create second snapshot
+ alt_snapshot_name = rand_name('test-snap-')
+ self.client.create_image(self.server['id'],
+ alt_snapshot_name)
+ except exceptions.Duplicate:
+ self.client.wait_for_image_status(image_id, 'ACTIVE')
+
+ else:
+ self.fail("Should not allow creating an image when another image "
+ "of the server is still being saved")
+
+ @attr(type='negative')
+ @unittest.skip("Until Bug 1004564 is fixed")
+ def test_create_image_specify_name_over_256_chars(self):
+ # Return an error if snapshot name over 256 characters is passed
+
+ try:
+ snapshot_name = rand_name('a' * 260)
+ self.assertRaises(exceptions.BadRequest, self.client.create_image,
+ self.server['id'], snapshot_name)
+ except Exception:
+ self.fail("Should return 400 Bad Request if image name is over 256"
+ " characters")
+
+ @attr(type='negative')
+ def test_delete_image_that_is_not_yet_active(self):
+ # Return an error while trying to delete an image what is creating
+
+ snapshot_name = rand_name('test-snap-')
+ resp, body = self.client.create_image(self.server['id'], snapshot_name)
+ self.assertEqual(202, resp.status)
+ image_id = parse_image_id(resp['location'])
+ self.image_ids.append(image_id)
+
+ # Do not wait, attempt to delete the image, ensure it's successful
+ resp, body = self.client.delete_image(image_id)
+ self.assertEqual('204', resp['status'])
+ self.image_ids.remove(image_id)
+
+ self.assertRaises(exceptions.NotFound, self.client.get_image, image_id)
+
+
+class ImagesOneServerTestJSON(base.BaseComputeTestJSON,
+ ImagesOneServerTestBase):
+
+ def tearDown(self):
+ ImagesOneServerTestBase.tearDown(self)
+
+ @classmethod
+ def setUpClass(cls):
+ super(ImagesOneServerTestJSON, cls).setUpClass()
+ cls.client = cls.images_client
+ cls.servers_client = cls.servers_client
+ cls.server = cls.create_server()
+
+ cls.image_ids = []
+
+ if compute.MULTI_USER:
+ if cls.config.compute.allow_tenant_isolation:
+ creds = cls._get_isolated_creds()
+ username, tenant_name, password = creds
+ cls.alt_manager = clients.Manager(username=username,
+ password=password,
+ tenant_name=tenant_name)
+ else:
+ # Use the alt_XXX credentials in the config file
+ cls.alt_manager = clients.AltManager()
+ cls.alt_client = cls.alt_manager.images_client
+
+
+class ImagesOneServerTestXML(base.BaseComputeTestXML,
+ ImagesOneServerTestBase):
+
+ def tearDown(self):
+ ImagesOneServerTestBase.tearDown(self)
+
+ @classmethod
+ def setUpClass(cls):
+ super(ImagesOneServerTestXML, cls).setUpClass()
+ cls.client = cls.images_client
+ cls.servers_client = cls.servers_client
+ cls.server = cls.create_server()
+
+ cls.image_ids = []
+
+ if compute.MULTI_USER:
+ if cls.config.compute.allow_tenant_isolation:
+ creds = cls._get_isolated_creds()
+ username, tenant_name, password = creds
+ cls.alt_manager = clients.Manager(username=username,
+ password=password,
+ tenant_name=tenant_name)
+ else:
+ # Use the alt_XXX credentials in the config file
+ cls.alt_manager = clients.AltManager()
+ cls.alt_client = cls.alt_manager.images_client
diff --git a/tempest/tests/compute/servers/test_list_server_filters.py b/tempest/tests/compute/servers/test_list_server_filters.py
index 5eea24f..d943e5d 100644
--- a/tempest/tests/compute/servers/test_list_server_filters.py
+++ b/tempest/tests/compute/servers/test_list_server_filters.py
@@ -208,7 +208,6 @@
ListServerFiltersTest):
@classmethod
def setUpClass(cls):
- raise nose.SkipTest("Until Bug 1039753 is fixed")
super(ListServerFiltersTestJSON, cls).setUpClass()
ListServerFiltersTest.setUpClass(cls)
@@ -222,7 +221,6 @@
ListServerFiltersTest):
@classmethod
def setUpClass(cls):
- raise nose.SkipTest("Until Bug 1039753 is fixed")
super(ListServerFiltersTestXML, cls).setUpClass()
ListServerFiltersTest.setUpClass(cls)
diff --git a/tempest/tests/compute/servers/test_list_servers_negative.py b/tempest/tests/compute/servers/test_list_servers_negative.py
index e98d8f0..035ffe8 100644
--- a/tempest/tests/compute/servers/test_list_servers_negative.py
+++ b/tempest/tests/compute/servers/test_list_servers_negative.py
@@ -131,7 +131,6 @@
self.assertEqual('200', resp['status'])
self.assertEqual([], servers)
- @unittest.skip("Skip until bug 1061712 is resolved")
def test_list_servers_status_non_existing(self):
# Return an empty list when invalid status is specified
non_existing_status = 'BALONEY'
diff --git a/tempest/tests/compute/servers/test_server_actions.py b/tempest/tests/compute/servers/test_server_actions.py
index 91f0674..2fe8464 100644
--- a/tempest/tests/compute/servers/test_server_actions.py
+++ b/tempest/tests/compute/servers/test_server_actions.py
@@ -34,18 +34,6 @@
resize_available = tempest.config.TempestConfig().compute.resize_available
run_ssh = tempest.config.TempestConfig().compute.run_ssh
- def setUp(self):
- self.name = rand_name('server')
- resp, server = self.create_server_with_extras(self.name,
- self.image_ref,
- self.flavor_ref)
- self.server_id = server['id']
- self.password = server['adminPass']
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- def tearDown(self):
- self.clear_servers()
-
@attr(type='smoke')
@unittest.skipUnless(compute.CHANGE_PASSWORD_AVAILABLE,
'Change password not available.')
@@ -207,27 +195,69 @@
class ServerActionsTestXML(base.BaseComputeTestXML,
ServerActionsTestBase):
+ def setUp(self):
+ super(ServerActionsTestXML, self).setUp()
+ # Check if the server is in a clean state after test
+ try:
+ self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ except exceptions:
+ # Rebuild server if something happened to it during a test
+ self.clear_servers()
+ resp, server = self.create_server_with_extras(self.name,
+ self.image_ref,
+ self.flavor_ref)
+ self.server_id = server['id']
+ self.password = server['adminPass']
+ self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+
@classmethod
def setUpClass(cls):
super(ServerActionsTestXML, cls).setUpClass()
cls.client = cls.servers_client
+ cls.name = rand_name('server')
+ resp, server = cls.create_server_with_extras(cls.name,
+ cls.image_ref,
+ cls.flavor_ref)
+ cls.server_id = server['id']
+ cls.password = server['adminPass']
+ cls.client.wait_for_server_status(cls.server_id, 'ACTIVE')
- def setUp(self):
- ServerActionsTestBase.setUp(self)
-
- def tearDown(self):
- ServerActionsTestBase.tearDown(self)
+ @classmethod
+ def tearDownClass(cls):
+ cls.clear_servers()
+ super(ServerActionsTestXML, cls).tearDownClass()
class ServerActionsTestJSON(base.BaseComputeTestJSON,
ServerActionsTestBase):
+ def setUp(self):
+ super(ServerActionsTestJSON, self).setUp()
+ # Check if the server is in a clean state after test
+ try:
+ self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ except exceptions:
+ # Rebuild server if something happened to it during a test
+ self.clear_servers()
+ resp, server = self.create_server_with_extras(self.name,
+ self.image_ref,
+ self.flavor_ref)
+ self.server_id = server['id']
+ self.password = server['adminPass']
+ self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+
@classmethod
def setUpClass(cls):
super(ServerActionsTestJSON, cls).setUpClass()
cls.client = cls.servers_client
+ cls.name = rand_name('server')
+ resp, server = cls.create_server_with_extras(cls.name,
+ cls.image_ref,
+ cls.flavor_ref)
+ cls.server_id = server['id']
+ cls.password = server['adminPass']
+ cls.client.wait_for_server_status(cls.server_id, 'ACTIVE')
- def setUp(self):
- ServerActionsTestBase.setUp(self)
-
- def tearDown(self):
- ServerActionsTestBase.tearDown(self)
+ @classmethod
+ def tearDownClass(cls):
+ cls.clear_servers()
+ super(ServerActionsTestJSON, cls).tearDownClass()
diff --git a/tempest/tests/compute/servers/test_server_basic_ops.py b/tempest/tests/compute/servers/test_server_basic_ops.py
index 3453d86..2183193 100644
--- a/tempest/tests/compute/servers/test_server_basic_ops.py
+++ b/tempest/tests/compute/servers/test_server_basic_ops.py
@@ -37,7 +37,7 @@
* Terminate the instance
"""
- def test_001_create_keypair(self):
+ def create_keypair(self):
kp_name = rand_name('keypair-smoke')
self.keypair = self.compute_client.keypairs.create(kp_name)
try:
@@ -46,7 +46,7 @@
except AttributeError:
self.fail("Keypair object not successfully created.")
- def test_002_create_security_group(self):
+ def create_security_group(self):
sg_name = rand_name('secgroup-smoke')
sg_desc = sg_name + " description"
self.secgroup = self.compute_client.security_groups.create(sg_name,
@@ -82,7 +82,7 @@
except Exception:
self.fail("Failed to create rule in security group.")
- def test_003_boot_instance(self):
+ def boot_instance(self):
i_name = rand_name('instance')
flavor_id = self.config.compute.flavor_ref
base_image_id = self.config.compute.image_ref
@@ -99,11 +99,11 @@
self.assertEqual(self.instance.status, 'BUILD')
- def test_004_wait_on_active(self):
+ def wait_on_active(self):
instance_id = self.get_resource('instance').id
self.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
- def test_005_pause_server(self):
+ def pause_server(self):
instance = self.get_resource('instance')
instance_id = instance.id
LOG.debug("Pausing instance %s. Current status: %s",
@@ -111,7 +111,7 @@
instance.pause()
self.status_timeout(self.compute_client.servers, instance_id, 'PAUSED')
- def test_006_unpause_server(self):
+ def unpause_server(self):
instance = self.get_resource('instance')
instance_id = instance.id
LOG.debug("Unpausing instance %s. Current status: %s",
@@ -119,7 +119,7 @@
instance.unpause()
self.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
- def test_007_suspend_server(self):
+ def suspend_server(self):
instance = self.get_resource('instance')
instance_id = instance.id
LOG.debug("Suspending instance %s. Current status: %s",
@@ -128,7 +128,7 @@
self.status_timeout(self.compute_client.servers,
instance_id, 'SUSPENDED')
- def test_008_resume_server(self):
+ def resume_server(self):
instance = self.get_resource('instance')
instance_id = instance.id
LOG.debug("Resuming instance %s. Current status: %s",
@@ -136,7 +136,18 @@
instance.resume()
self.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
- def test_099_terminate_instance(self):
+ def terminate_instance(self):
instance = self.get_resource('instance')
instance.delete()
self.remove_resource('instance')
+
+ def test_server_basicops(self):
+ self.create_keypair()
+ self.create_security_group()
+ self.boot_instance()
+ self.wait_on_active()
+ self.pause_server()
+ self.unpause_server()
+ self.suspend_server()
+ self.resume_server()
+ self.terminate_instance()
diff --git a/tempest/tests/compute/servers/test_servers_negative.py b/tempest/tests/compute/servers/test_servers_negative.py
index 970f6bc..f7624b3 100644
--- a/tempest/tests/compute/servers/test_servers_negative.py
+++ b/tempest/tests/compute/servers/test_servers_negative.py
@@ -176,7 +176,7 @@
# Pass invalid network uuid while creating a server
server_name = rand_name('server')
- networks = [{'fixed_ip': '10.0.1.1', 'uuid':'a-b-c-d-e-f-g-h-i-j'}]
+ networks = [{'fixed_ip': '10.0.1.1', 'uuid': 'a-b-c-d-e-f-g-h-i-j'}]
self.assertRaises(exceptions.BadRequest,
self.create_server_with_extras,
@@ -194,7 +194,6 @@
server_name, self.image_ref, self.flavor_ref,
key_name=key_name)
- @unittest.skip("Until Bug 1004007 is fixed")
@attr(type='negative')
def test_create_server_metadata_exceeds_length_limit(self):
# Pass really long metadata while creating a server
diff --git a/tempest/tests/identity/admin/test_users.py b/tempest/tests/identity/admin/test_users.py
index 27a214c..7ad932b 100644
--- a/tempest/tests/identity/admin/test_users.py
+++ b/tempest/tests/identity/admin/test_users.py
@@ -60,7 +60,6 @@
self.alt_email)
@attr(type='negative')
- @unittest.skip("Until Bug 966251 is fixed")
def test_create_user_with_name_length_over_64(self):
# Length of user name filed should be restricted to 64 characters
self.data.setup_test_tenant()
@@ -172,7 +171,6 @@
self.data.test_tenant)
@attr(type='negative')
- @unittest.skip('Until Bug 988920 is fixed')
def test_authentication_when_tenant_is_disabled(self):
# User's token for a disabled tenant should not be authenticated
self.data.setup_test_user()
@@ -183,10 +181,9 @@
self.data.test_tenant)
@attr(type='negative')
- @unittest.skip('Until Bug 988920 is fixed')
def test_authentication_with_invalid_tenant(self):
# User's token for an invalid tenant should not be authenticated
- self.data.setup_one_user()
+ self.data.setup_test_user()
self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
self.data.test_user,
self.data.test_password,
@@ -195,6 +192,7 @@
@attr(type='negative')
def test_authentication_with_invalid_username(self):
# Non-existent user's token should not get authenticated
+ self.data.setup_test_user()
self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
'junkuser123', self.data.test_password,
self.data.test_tenant)
diff --git a/tempest/tests/identity/base.py b/tempest/tests/identity/base.py
index ce160da..8fee7ef 100644
--- a/tempest/tests/identity/base.py
+++ b/tempest/tests/identity/base.py
@@ -48,7 +48,7 @@
def disable_tenant(self, tenant_name):
tenant = self.get_tenant_by_name(tenant_name)
- self.client.update_tenant(tenant['id'], tenant['description'], False)
+ self.client.update_tenant(tenant['id'], enabled=False)
def get_user_by_name(self, name):
_, users = self.client.get_users()
diff --git a/tempest/tests/object_storage/base.py b/tempest/tests/object_storage/base.py
index 3992b13..10e2269 100644
--- a/tempest/tests/object_storage/base.py
+++ b/tempest/tests/object_storage/base.py
@@ -21,6 +21,7 @@
from tempest import clients
import tempest.config
from tempest import exceptions
+from tempest.tests.identity.base import DataGenerator
class BaseObjectTest(unittest.TestCase):
@@ -33,6 +34,16 @@
cls.account_client = cls.os.account_client
cls.config = cls.os.config
cls.custom_object_client = cls.os.custom_object_client
+ cls.os_admin = clients.IdentityManager()
+ cls.token_client = cls.os_admin.token_client
+ cls.admin_client = cls.os_admin.admin_client
+ cls.custom_account_client = cls.os.custom_account_client
+ cls.os_alt = clients.AltManager()
+ cls.object_client_alt = cls.os_alt.object_client
+ cls.container_client_alt = cls.os_alt.container_client
+ cls.admin_client_alt = cls.os_alt.admin_client
+
+ cls.data = DataGenerator(cls.admin_client)
try:
cls.account_client.list_account_containers()
diff --git a/tempest/tests/object_storage/test_account_services.py b/tempest/tests/object_storage/test_account_services.py
index cae2da1..e34e349 100644
--- a/tempest/tests/object_storage/test_account_services.py
+++ b/tempest/tests/object_storage/test_account_services.py
@@ -17,6 +17,7 @@
from nose.plugins.attrib import attr
from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
from tempest.tests.object_storage import base
@@ -80,3 +81,30 @@
resp, metadata = self.account_client.list_account_metadata()
self.assertNotIn('x-account-meta-test-account-meta', resp)
+
+ @attr(type='negative')
+ def test_list_containers_with_non_authorized_user(self):
+ #Listing containers with using non authorized user
+
+ # Randomly creating user
+ self.data.setup_test_user()
+
+ resp, body = \
+ self.token_client.auth(self.data.test_user,
+ self.data.test_password,
+ self.data.test_tenant)
+ new_token = \
+ self.token_client.get_token(self.data.test_user,
+ self.data.test_password,
+ self.data.test_tenant)
+
+ custom_headers = {'X-Auth-Token': new_token}
+
+ params = {'format': 'json'}
+ # Trying to list containers with non authorized user token
+ self.assertRaises(exceptions.Unauthorized,
+ self.custom_account_client.list_account_containers,
+ params=params, metadata=custom_headers)
+
+ #Attempt to the delete the user setup created
+ self.data.teardown_all()
diff --git a/tempest/tests/object_storage/test_object_services.py b/tempest/tests/object_storage/test_object_services.py
index 8b87ad6..fc3f45f 100644
--- a/tempest/tests/object_storage/test_object_services.py
+++ b/tempest/tests/object_storage/test_object_services.py
@@ -21,6 +21,8 @@
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
from tempest.tests.object_storage import base
+from time import time
+import unittest2 as unittest
class ObjectTest(base.BaseObjectTest):
@@ -33,6 +35,20 @@
cls.container_name = rand_name(name='TestContainer')
cls.container_client.create_container(cls.container_name)
+ # Randomly creating user
+ cls.data.setup_test_user()
+
+ resp, body = \
+ cls.token_client.auth(cls.data.test_user,
+ cls.data.test_password,
+ cls.data.test_tenant)
+ cls.new_token = \
+ cls.token_client.get_token(cls.data.test_user,
+ cls.data.test_password,
+ cls.data.test_tenant)
+
+ cls.custom_headers = {'X-Auth-Token': cls.new_token}
+
@classmethod
def tearDownClass(cls):
#Get list of all object in the container
@@ -47,6 +63,9 @@
#Attempt to delete the container
resp, _ = cls.container_client.delete_container(cls.container_name)
+ #Attempt to the delete the user setup created
+ cls.data.teardown_all()
+
@attr(type='smoke')
def test_create_object(self):
# Create storage object, test response
@@ -316,10 +335,184 @@
self.assertIn('x-container-read', resp)
self.assertEqual(resp['x-container-read'], 'x')
+ @unittest.skip('Until Bug 1091669 is resolved.')
+ @attr(type='smoke')
+ def test_access_public_object_with_another_user_creds(self):
+ #Make container public-readable, and access the object
+ #anonymously, e.g. using another user credentials
+
+ try:
+ resp_meta = None
+ cont_headers = {'X-Container-Read': '.r:*,.rlistings'}
+ resp_meta, body = \
+ self.container_client.update_container_metadata(
+ self.container_name, metadata=cont_headers,
+ metadata_prefix='')
+ self.assertEqual(resp_meta['status'], '204')
+ # Create Object
+ object_name = rand_name(name='Object')
+ data = arbitrary_string(size=len(object_name) * 1,
+ base_text=object_name)
+ resp, _ = self.object_client.create_object(self.container_name,
+ object_name, data)
+ self.assertEqual(resp['status'], '201')
+
+ # List container metadata
+ resp, _ = \
+ self.container_client.list_container_metadata(
+ self.container_name)
+ self.assertEqual(resp['status'], '204')
+ self.assertIn('x-container-read', resp)
+ self.assertEqual(resp['x-container-read'], '.r:*,.rlistings')
+
+ # Trying to GET Auth Token of Alternate user
+ token = self.admin_client_alt.get_auth()
+ headers = {'X-Auth-Token': token}
+
+ # Trying to create object with Alternate user creds
+ resp, body = \
+ self.custom_object_client.get_object(
+ self.container_name, object_name, metadata=headers)
+ self.assertEqual(body, data)
+
+ except Exception as e:
+ self.fail("Failed to get public readable object with another"
+ " user creds raised exception is %s" % e)
+
+ finally:
+ if resp_meta['status'] == '204':
+ # Delete updated container metadata, to revert back.
+ resp, body = \
+ self.container_client.delete_container_metadata(
+ self.container_name, metadata=cont_headers,
+ metadata_prefix='')
+
+ resp, _ = \
+ self.container_client.list_container_metadata(
+ self.container_name)
+ self.assertEqual(resp['status'], '204')
+ self.assertIn('x-container-read', resp)
+ self.assertEqual(resp['x-container-read'], 'x')
+
+ @unittest.skip('Until Bug #1020722 is resolved.')
+ @attr(type='smoke')
+ def test_write_public_object_without_using_creds(self):
+ #Make container public-writable, and create object
+ #anonymously, e.g. without using credentials
+ try:
+ resp_meta = None
+ # Update Container Metadata to make public readable
+ cont_headers = {'X-Container-Write': '-*'}
+ resp_meta, body = \
+ self.container_client.update_container_metadata(
+ self.container_name, metadata=cont_headers,
+ metadata_prefix='')
+ self.assertEqual(resp_meta['status'], '204')
+ # List container metadata
+ resp, _ = \
+ self.container_client.list_container_metadata(
+ self.container_name)
+
+ self.assertEqual(resp['status'], '204')
+ self.assertIn('x-container-write', resp)
+ self.assertEqual(resp['x-container-write'], '-*')
+
+ object_name = rand_name(name='Object')
+ data = arbitrary_string(size=len(object_name),
+ base_text=object_name)
+
+ headers = {'Content-Type': 'application/json',
+ 'Accept': 'application/json'}
+
+ #Trying to Create object without using creds
+ resp, body = \
+ self.custom_object_client.create_object(self.container_name,
+ object_name, data,
+ metadata=headers)
+ self.assertEqual(resp['status'], '201')
+
+ except Exception as e:
+ self.fail("Failed to create public writable object without using"
+ " creds raised exception is %s" % e)
+
+ finally:
+ if resp_meta['status'] == '204':
+ # Delete updated container metadata, to revert back.
+ resp, body = \
+ self.container_client.delete_container_metadata(
+ self.container_name, metadata=cont_headers,
+ metadata_prefix='')
+
+ resp, _ = \
+ self.container_client.list_container_metadata(
+ self.container_name)
+ self.assertEqual(resp['status'], '204')
+ self.assertIn('x-container-write', resp)
+ self.assertEqual(resp['x-container-write'], 'x')
+
+ @unittest.skip('Until Bug #1020722 is resolved.')
+ @attr(type='smoke')
+ def test_write_public_with_another_user_creds(self):
+ #Make container public-writable, and create object
+ #anonymously, e.g. with another user credentials
+
+ try:
+ resp_meta = None
+ # Update Container Metadata to make public readable
+ cont_headers = {'X-Container-Write': '-*'}
+ resp_meta, body = \
+ self.container_client.update_container_metadata(
+ self.container_name, metadata=cont_headers,
+ metadata_prefix='')
+ self.assertEqual(resp_meta['status'], '204')
+ # List container metadata
+ resp, _ = \
+ self.container_client.list_container_metadata(
+ self.container_name)
+
+ self.assertEqual(resp['status'], '204')
+ self.assertIn('x-container-write', resp)
+ self.assertEqual(resp['x-container-write'], '-*')
+
+ #Trying to GET auth token of Alternate user
+ token = self.admin_client_alt.get_auth()
+
+ headers = {'Content-Type': 'application/json',
+ 'Accept': 'application/json',
+ 'X-Auth-Token': token}
+
+ #Trying to Create an object with another user creds
+ object_name = rand_name(name='Object')
+ data = arbitrary_string(size=len(object_name),
+ base_text=object_name)
+ resp, body = \
+ self.custom_object_client.create_object(
+ self.container_name, object_name, data, metadata=headers)
+ self.assertEqual(resp['status'], '201')
+
+ except Exception as e:
+ self.fail("Failed to create public writable object with another"
+ " user creds raised exception is %s" % e)
+
+ finally:
+ if resp_meta['status'] == '204':
+ # Delete updated container metadata, to revert back.
+ resp, body = \
+ self.container_client.delete_container_metadata(
+ self.container_name, metadata=cont_headers,
+ metadata_prefix='')
+
+ resp, _ = \
+ self.container_client.list_container_metadata(
+ self.container_name)
+ self.assertEqual(resp['status'], '204')
+ self.assertIn('x-container-write', resp)
+ self.assertEqual(resp['x-container-write'], 'x')
+
@attr(type='negative')
def test_access_object_without_using_creds(self):
# Attempt to access the object anonymously, e.g.
- # not using any credentials
+ # not using any credentials
# Create Object
object_name = rand_name(name='Object')
@@ -354,7 +547,7 @@
@attr(type='negative')
def test_delete_object_without_using_creds(self):
# Attempt to delete the object anonymously,
- # e.g. not using any credentials
+ # e.g. not using any credentials
# Create Object
object_name = rand_name(name='Object')
@@ -367,3 +560,99 @@
self.assertRaises(exceptions.Unauthorized,
self.custom_object_client.delete_object,
self.container_name, object_name)
+
+ @attr(type='negative')
+ def test_write_object_with_non_authorized_user(self):
+ #Attempt to upload another file using non authorized user
+
+ object_name = rand_name(name='Object')
+ data = arbitrary_string(size=len(object_name) * 5,
+ base_text=object_name)
+
+ # Trying to Create Object with non authorized user token
+ self.assertRaises(exceptions.Unauthorized,
+ self.custom_object_client.create_object,
+ self.container_name, object_name, data,
+ metadata=self.custom_headers)
+
+ @attr(type='negative')
+ def test_read_object_with_non_authorized_user(self):
+ #Attempt to download the file using non authorized user
+
+ object_name = rand_name(name='Object')
+ data = arbitrary_string(size=len(object_name) * 5,
+ base_text=object_name)
+
+ resp, body = \
+ self.object_client.create_object(self.container_name,
+ object_name, data)
+ self.assertEqual(resp['status'], '201')
+
+ # Trying to Get Object with non authorized user token
+ self.assertRaises(exceptions.Unauthorized,
+ self.custom_object_client.get_object,
+ self.container_name, object_name,
+ metadata=self.custom_headers)
+
+ @attr(type='negative')
+ def test_delete_object_with_non_authorized_user(self):
+ #Attempt to delete container using non authorized user
+
+ object_name = rand_name(name='Object')
+ data = arbitrary_string(size=len(object_name) * 5,
+ base_text=object_name)
+
+ resp, body = \
+ self.object_client.create_object(self.container_name,
+ object_name, data)
+ self.assertEqual(resp['status'], '201')
+
+ # Trying to Delete Object with non authorized user token
+ self.assertRaises(exceptions.Unauthorized,
+ self.custom_object_client.delete_object,
+ self.container_name, object_name,
+ metadata=self.custom_headers)
+
+ @unittest.skip('Until bug 1097137 is resolved.')
+ @attr(type='positive')
+ def test_get_object_using_temp_url(self):
+ #Access object using temp url within expiry time
+
+ try:
+ #Update Account Metadata
+ # Flag to check if account metadata got updated
+ flag = False
+ key = 'Meta'
+ metadata = {'Temp-URL-Key': key}
+ resp, _ = \
+ self.account_client.create_account_metadata(metadata=metadata)
+ self.assertEqual(resp['status'], '204')
+ flag = True
+
+ resp, _ = self.account_client.list_account_metadata()
+ self.assertIn('x-account-meta-temp-url-key', resp)
+ self.assertEqual(resp['x-account-meta-temp-url-key'], key)
+
+ # Create Object
+ object_name = rand_name(name='ObjectTemp')
+ data = arbitrary_string(size=len(object_name),
+ base_text=object_name)
+ self.object_client.create_object(self.container_name,
+ object_name, data)
+
+ expires = int(time() + 10)
+
+ #Trying to GET object using temp URL with in expiry time
+ _, body = \
+ self.object_client.get_object_using_temp_url(
+ self.container_name, object_name, expires, key)
+
+ self.assertEqual(body, data)
+
+ finally:
+ if flag:
+ resp, _ = \
+ self.account_client.delete_account_metadata(
+ metadata=metadata)
+ resp, _ = self.account_client.list_account_metadata()
+ self.assertNotIn('x-account-meta-temp-url-key', resp)
diff --git a/tempest/tests/volume/admin/base.py b/tempest/tests/volume/admin/base.py
index 81c7c78..d35efbc 100644
--- a/tempest/tests/volume/admin/base.py
+++ b/tempest/tests/volume/admin/base.py
@@ -35,7 +35,7 @@
cls.adm_user = cls.config.compute_admin.username
cls.adm_pass = cls.config.compute_admin.password
cls.adm_tenant = cls.config.compute_admin.tenant_name
- cls.auth_url = cls.config.identity.auth_url
+ cls.auth_url = cls.config.identity.uri
if not cls.adm_user and cls.adm_pass and cls.adm_tenant:
msg = ("Missing Volume Admin API credentials "
diff --git a/tempest/tests/volume/admin/test_volume_types.py b/tempest/tests/volume/admin/test_volume_types.py
index 65c975a..a907a79 100644
--- a/tempest/tests/volume/admin/test_volume_types.py
+++ b/tempest/tests/volume/admin/test_volume_types.py
@@ -28,7 +28,7 @@
adm_user = cls.config.compute_admin.username
adm_pass = cls.config.compute_admin.password
adm_tenant = cls.config.compute_admin.tenant_name
- auth_url = cls.config.identity.auth_url
+ auth_url = cls.config.identity.uri
cls.client = volume_types_client.VolumeTypesClientJSON(cls.config,
adm_user,
diff --git a/tempest/tests/volume/admin/test_volume_types_extra_specs.py b/tempest/tests/volume/admin/test_volume_types_extra_specs.py
index 9734c42..c5a1fa9 100644
--- a/tempest/tests/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/tests/volume/admin/test_volume_types_extra_specs.py
@@ -29,7 +29,7 @@
adm_user = cls.config.compute_admin.username
adm_pass = cls.config.compute_admin.password
adm_tenant = cls.config.compute_admin.tenant_name
- auth_url = cls.config.identity.auth_url
+ auth_url = cls.config.identity.uri
cls.client = volume_types_client.VolumeTypesClientJSON(cls.config,
adm_user,
diff --git a/tools/install_venv.py b/tools/install_venv.py
index 42ed32c..28275ba 100644
--- a/tools/install_venv.py
+++ b/tools/install_venv.py
@@ -95,9 +95,9 @@
class Fedora(Distro):
- """This covers all Fedora-based distributions.
+ """This covers Fedora-based distributions.
- Includes: Fedora, RHEL, CentOS, Scientific Linux"""
+ Includes: Fedora, RHEL, Scientific Linux"""
def check_pkg(self, pkg):
return run_command_with_code(['rpm', '-q', pkg],
@@ -141,12 +141,25 @@
'contrib/redhat-eventlet.patch')
+class CentOS(Fedora):
+ """This covers CentOS."""
+
+ def post_process(self):
+ if not self.check_pkg('openssl-devel'):
+ self.yum.install('openssl-devel', check_exit_code=False)
+
+
def get_distro():
- if (os.path.exists('/etc/fedora-release') or
- os.path.exists('/etc/redhat-release')):
+ if os.path.exists('/etc/redhat-release'):
+ with open('/etc/redhat-release') as rh_release:
+ if 'CentOS' in rh_release.read():
+ return CentOS()
return Fedora()
- else:
- return Distro()
+
+ if os.path.exists('/etc/fedora-release'):
+ return Fedora()
+
+ return Distro()
def check_dependencies():
diff --git a/tools/tempest_coverage.py b/tools/tempest_coverage.py
index 73dcfbc..6e7ac04 100755
--- a/tools/tempest_coverage.py
+++ b/tools/tempest_coverage.py
@@ -139,7 +139,7 @@
def main(argv):
CLI = parse_opts(argv)
client_args = (CONF, CONF.compute_admin.username,
- CONF.compute_admin.password, CONF.identity.auth_url,
+ CONF.compute_admin.password, CONF.identity.uri,
CONF.compute_admin.tenant_name)
coverage_client = CoverageClientJSON(*client_args)
diff --git a/tools/test-requires b/tools/test-requires
index fa98918..d3c7a1e 100644
--- a/tools/test-requires
+++ b/tools/test-requires
@@ -1,5 +1,4 @@
pep8==1.3.3
pylint==0.19
# Needed for whitebox testing
-paramiko
sqlalchemy