Merge "Handling rate-limit for JSON request- rest_client"
diff --git a/HACKING.rst b/HACKING.rst
index 103f8cd..fed4130 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -56,8 +56,8 @@
import logging
import random
import StringIO
+ import testtools
import time
- import unittest
import eventlet
import webob.exc
diff --git a/etc/TEMPEST_README.txt b/etc/TEMPEST_README.txt
index e46e195..50fa688 100644
--- a/etc/TEMPEST_README.txt
+++ b/etc/TEMPEST_README.txt
@@ -2,13 +2,6 @@
-rename the /etc/tempest.conf.sample file to tempest.conf
-Set the fields in the file to values relevant to your system
-Set the "authentication" value (basic or keystone_v2 currently supported)
--from the root directory of the project, run "nosetests tempest/tests" to
- run all tests
-
-TODO:
-Use virtualenv to install all needed packages. Till then, the following
-packages must be installed:
--httplib2
--unittest2
--paramiko
--nose
\ No newline at end of file
+-From the root directory of the project, run "./run_tests.sh" this will
+create the venv to install the project dependencies and run nosetests tempest
+to run all the tests
diff --git a/tempest/clients.py b/tempest/clients.py
index 29e83bf..7a7ea13 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -32,7 +32,7 @@
from tempest.services.compute.json.security_groups_client import \
SecurityGroupsClientJSON
from tempest.services.compute.json.keypairs_client import KeyPairsClientJSON
-from tempest.services.compute.json.quotas_client import QuotasClient
+from tempest.services.compute.json.quotas_client import QuotasClientJSON
from tempest.services.compute.json.volumes_extensions_client import \
VolumesExtensionsClientJSON
from tempest.services.compute.json.console_output_client import \
@@ -44,6 +44,7 @@
from tempest.services.compute.xml.images_client import ImagesClientXML
from tempest.services.compute.xml.keypairs_client import KeyPairsClientXML
from tempest.services.compute.xml.limits_client import LimitsClientXML
+from tempest.services.compute.xml.quotas_client import QuotasClientXML
from tempest.services.compute.xml.security_groups_client \
import SecurityGroupsClientXML
from tempest.services.compute.xml.servers_client import ServersClientXML
@@ -79,6 +80,11 @@
"xml": KeyPairsClientXML,
}
+QUOTAS_CLIENTS = {
+ "json": QuotasClientJSON,
+ "xml": QuotasClientXML,
+}
+
SERVERS_CLIENTS = {
"json": ServersClientJSON,
"xml": ServersClientXML,
@@ -180,6 +186,7 @@
self.limits_client = LIMITS_CLIENTS[interface](*client_args)
self.images_client = IMAGES_CLIENTS[interface](*client_args)
self.keypairs_client = KEYPAIRS_CLIENTS[interface](*client_args)
+ self.quotas_client = QUOTAS_CLIENTS[interface](*client_args)
self.flavors_client = FLAVORS_CLIENTS[interface](*client_args)
ext_cli = EXTENSIONS_CLIENTS[interface](*client_args)
self.extensions_client = ext_cli
@@ -196,7 +203,6 @@
except KeyError:
msg = "Unsupported interface type `%s'" % interface
raise exceptions.InvalidConfiguration(msg)
- self.quotas_client = QuotasClient(*client_args)
self.network_client = NetworkClient(*client_args)
self.account_client = AccountClient(*client_args)
self.container_client = ContainerClient(*client_args)
diff --git a/tempest/manager.py b/tempest/manager.py
index 4137ec3..cb1e52d 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -55,7 +55,7 @@
VolumesExtensionsClient = volumes_extensions_client.VolumesExtensionsClientJSON
VolumesClient = volumes_client.VolumesClientJSON
ConsoleOutputsClient = console_output_client.ConsoleOutputsClientJSON
-QuotasClient = quotas_client.QuotasClient
+QuotasClient = quotas_client.QuotasClientJSON
LOG = logging.getLogger(__name__)
diff --git a/tempest/services/compute/admin/json/quotas_client.py b/tempest/services/compute/admin/json/quotas_client.py
index 625d4d4..0a4bd72 100644
--- a/tempest/services/compute/admin/json/quotas_client.py
+++ b/tempest/services/compute/admin/json/quotas_client.py
@@ -17,14 +17,14 @@
import json
-from tempest.services.compute.json.quotas_client import QuotasClient
+from tempest.services.compute.json.quotas_client import QuotasClientJSON
-class AdminQuotasClient(QuotasClient):
+class AdminQuotasClientJSON(QuotasClientJSON):
def __init__(self, config, username, password, auth_url, tenant_name=None):
- super(AdminQuotasClient, self).__init__(config, username, password,
- auth_url, tenant_name)
+ super(AdminQuotasClientJSON, self).__init__(config, username, password,
+ auth_url, tenant_name)
def update_quota_set(self, tenant_id, injected_file_content_bytes=None,
metadata_items=None, ram=None, floating_ips=None,
diff --git a/tempest/services/compute/admin/xml/__init__.py b/tempest/services/compute/admin/xml/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/compute/admin/xml/__init__.py
diff --git a/tempest/services/compute/admin/xml/quotas_client.py b/tempest/services/compute/admin/xml/quotas_client.py
new file mode 100644
index 0000000..d567a9c
--- /dev/null
+++ b/tempest/services/compute/admin/xml/quotas_client.py
@@ -0,0 +1,88 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2012 NTT Data
+# 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 urllib
+
+from lxml import etree
+
+from tempest.common.rest_client import RestClientXML
+from tempest.services.compute.xml.common import Document
+from tempest.services.compute.xml.common import Element
+from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml.common import XMLNS_11
+from tempest.services.compute.xml.quotas_client import QuotasClientXML
+
+
+class AdminQuotasClientXML(QuotasClientXML):
+
+ def __init__(self, config, username, password, auth_url, tenant_name=None):
+ super(AdminQuotasClientXML, self).__init__(config, username, password,
+ auth_url, tenant_name)
+
+ def update_quota_set(self, tenant_id, injected_file_content_bytes=None,
+ metadata_items=None, ram=None, floating_ips=None,
+ key_pairs=None, instances=None,
+ security_group_rules=None, injected_files=None,
+ cores=None, injected_file_path_bytes=None,
+ security_groups=None):
+ """
+ Updates the tenant's quota limits for one or more resources
+ """
+ post_body = Element("quota_set",
+ xmlns=XMLNS_11)
+
+ if injected_file_content_bytes is not None:
+ post_body.add_attr('injected_file_content_bytes',
+ injected_file_content_bytes)
+
+ if metadata_items is not None:
+ post_body.add_attr('metadata_items', metadata_items)
+
+ if ram is not None:
+ post_body.add_attr('ram', ram)
+
+ if floating_ips is not None:
+ post_body.add_attr('floating_ips', floating_ips)
+
+ if key_pairs is not None:
+ post_body.add_attr('key_pairs', key_pairs)
+
+ if instances is not None:
+ post_body.add_attr('instances', instances)
+
+ if security_group_rules is not None:
+ post_body.add_attr('security_group_rules', security_group_rules)
+
+ if injected_files is not None:
+ post_body.add_attr('injected_files', injected_files)
+
+ if cores is not None:
+ post_body.add_attr('cores', cores)
+
+ if injected_file_path_bytes is not None:
+ post_body.add_attr('injected_file_path_bytes',
+ injected_file_path_bytes)
+
+ if security_groups is not None:
+ post_body.add_attr('security_groups', security_groups)
+
+ resp, body = self.put('os-quota-sets/%s' % str(tenant_id),
+ str(Document(post_body)),
+ self.headers)
+ body = xml_to_json(etree.fromstring(body))
+ body = self._format_quota(body)
+ return resp, body
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 543b015..a95ff1c 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -20,11 +20,11 @@
from tempest.common.rest_client import RestClient
-class QuotasClient(RestClient):
+class QuotasClientJSON(RestClient):
def __init__(self, config, username, password, auth_url, tenant_name=None):
- super(QuotasClient, self).__init__(config, username, password,
- auth_url, tenant_name)
+ super(QuotasClientJSON, self).__init__(config, username, password,
+ auth_url, tenant_name)
self.service = self.config.compute.catalog_type
def get_quota_set(self, tenant_id):
diff --git a/tempest/services/compute/xml/quotas_client.py b/tempest/services/compute/xml/quotas_client.py
new file mode 100644
index 0000000..8978214
--- /dev/null
+++ b/tempest/services/compute/xml/quotas_client.py
@@ -0,0 +1,58 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2012 NTT Data
+# 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 urllib
+
+from lxml import etree
+
+from tempest.common.rest_client import RestClientXML
+from tempest.services.compute.xml.common import Document
+from tempest.services.compute.xml.common import Element
+from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml.common import XMLNS_11
+
+
+class QuotasClientXML(RestClientXML):
+
+ def __init__(self, config, username, password, auth_url, tenant_name=None):
+ super(QuotasClientXML, self).__init__(config, username, password,
+ auth_url, tenant_name)
+ self.service = self.config.compute.catalog_type
+
+ def _format_quota(self, q):
+ quota = {}
+ for k, v in q.items():
+ try:
+ v = int(v)
+ except ValueError:
+ pass
+
+ quota[k] = v
+
+ return quota
+
+ def _parse_array(self, node):
+ return [self._format_quota(xml_to_json(x)) for x in node]
+
+ def get_quota_set(self, tenant_id):
+ """List the quota set for a tenant."""
+
+ url = 'os-quota-sets/%s' % str(tenant_id)
+ resp, body = self.get(url, self.headers)
+ body = xml_to_json(etree.fromstring(body))
+ body = self._format_quota(body)
+ return resp, body
diff --git a/tempest/test.py b/tempest/test.py
index dc480d1..7804e12 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -18,14 +18,14 @@
import logging
import time
-import unittest2 as unittest
+import testtools
from tempest import manager
LOG = logging.getLogger(__name__)
-class TestCase(unittest.TestCase):
+class TestCase(testtools.TestCase):
"""
Base test case class for all Tempest tests
diff --git a/tempest/testboto.py b/tempest/testboto.py
index 29ac3ca..7031fe2 100644
--- a/tempest/testboto.py
+++ b/tempest/testboto.py
@@ -25,9 +25,8 @@
from boto.exception import EC2ResponseError
from boto.s3.bucket import Bucket
from boto.s3.key import Key
-import nose
import testresources
-import unittest2 as unittest
+import testtools
from tempest.exceptions import TearDownException
import tempest.tests.boto
@@ -123,11 +122,11 @@
return string + ")"
-class BotoTestCase(unittest.TestCase,
+class BotoTestCase(testtools.TestCase,
testresources.ResourcedTestCase):
"""Recommended to use as base class for boto related test."""
- resources = [('boto_init', tempest.tests.boto.generic_setup_package())]
+ resources = [('boto_init', tempest.tests.boto.BotoResource())]
@classmethod
def setUpClass(cls):
@@ -137,11 +136,11 @@
cls._sequence = -1
if (hasattr(cls, "EC2") and
tempest.tests.boto.EC2_CAN_CONNECT_ERROR is not None):
- raise nose.SkipTest("EC2 " + cls.__name__ + ": " +
+ raise cls.skipException("EC2 " + cls.__name__ + ": " +
tempest.tests.boto.EC2_CAN_CONNECT_ERROR)
if (hasattr(cls, "S3") and
tempest.tests.boto.S3_CAN_CONNECT_ERROR is not None):
- raise nose.SkipTest("S3 " + cls.__name__ + ": " +
+ raise cls.skipException("S3 " + cls.__name__ + ": " +
tempest.tests.boto.S3_CAN_CONNECT_ERROR)
@classmethod
diff --git a/tempest/tests/boto/__init__.py b/tempest/tests/boto/__init__.py
index 6d5149e..99dd8a9 100644
--- a/tempest/tests/boto/__init__.py
+++ b/tempest/tests/boto/__init__.py
@@ -26,6 +26,7 @@
import tempest.clients
from tempest.common.utils.file_utils import have_effective_read_access
import tempest.config
+from testresources import TestResourceManager
A_I_IMAGES_READY = False # ari,ami,aki
S3_CAN_CONNECT_ERROR = "Unknown Error"
@@ -96,3 +97,8 @@
else:
S3_CAN_CONNECT_ERROR = None
boto_logger.setLevel(level)
+
+
+class BotoResource(TestResourceManager):
+ def make(self, dependency_resources=None):
+ return generic_setup_package()
diff --git a/tempest/tests/boto/test_ec2_instance_run.py b/tempest/tests/boto/test_ec2_instance_run.py
index 6a8778a..1adb5fb 100644
--- a/tempest/tests/boto/test_ec2_instance_run.py
+++ b/tempest/tests/boto/test_ec2_instance_run.py
@@ -20,9 +20,8 @@
from boto.exception import EC2ResponseError
from boto.s3.key import Key
-import nose
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
@@ -44,8 +43,8 @@
def setUpClass(cls):
super(InstanceRunTest, cls).setUpClass()
if not tempest.tests.boto.A_I_IMAGES_READY:
- raise nose.SkipTest("".join(("EC2 ", cls.__name__,
- ": requires ami/aki/ari manifest")))
+ raise cls.skipException("".join(("EC2 ", cls.__name__,
+ ": requires ami/aki/ari manifest")))
cls.os = clients.Manager()
cls.s3_client = cls.os.s3_client
cls.ec2_client = cls.os.ec2api_client
@@ -122,7 +121,7 @@
self.cancelResourceCleanUp(rcuk)
@attr(type='smoke')
- @unittest.skip("Skipped until the Bug #1098891 is resolved")
+ @testtools.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"]
diff --git a/tempest/tests/boto/test_ec2_keys.py b/tempest/tests/boto/test_ec2_keys.py
index fcec02d..540374a 100644
--- a/tempest/tests/boto/test_ec2_keys.py
+++ b/tempest/tests/boto/test_ec2_keys.py
@@ -16,7 +16,7 @@
# under the License.
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
@@ -47,7 +47,7 @@
self.client.get_key_pair(key_name)))
@attr(type='smoke')
- @unittest.skip("Skipped until the Bug #1072318 is resolved")
+ @testtools.skip("Skipped until the Bug #1072318 is resolved")
def test_delete_ec2_keypair(self):
# EC2 delete KeyPair
key_name = rand_name("keypair-")
@@ -65,7 +65,7 @@
self.client.get_key_pair(key_name)))
@attr(type='smoke')
- @unittest.skip("Skipped until the Bug #1072762 is resolved")
+ @testtools.skip("Skipped until the Bug #1072762 is resolved")
def test_duplicate_ec2_keypair(self):
# EC2 duplicate KeyPair
key_name = rand_name("keypair-")
diff --git a/tempest/tests/boto/test_ec2_network.py b/tempest/tests/boto/test_ec2_network.py
index 27649e6..76103c2 100644
--- a/tempest/tests/boto/test_ec2_network.py
+++ b/tempest/tests/boto/test_ec2_network.py
@@ -16,7 +16,7 @@
# under the License.
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.testboto import BotoTestCase
@@ -32,7 +32,7 @@
cls.client = cls.os.ec2api_client
#Note(afazekas): these tests for things duable without an instance
- @unittest.skip("Skipped until the Bug #1080406 is resolved")
+ @testtools.skip("Skipped until the Bug #1080406 is resolved")
@attr(type='smoke')
def test_disassociate_not_associated_floating_ip(self):
# EC2 disassociate not associated floating ip
diff --git a/tempest/tests/boto/test_ec2_security_groups.py b/tempest/tests/boto/test_ec2_security_groups.py
index 09da82c..ed7bedb 100644
--- a/tempest/tests/boto/test_ec2_security_groups.py
+++ b/tempest/tests/boto/test_ec2_security_groups.py
@@ -16,7 +16,7 @@
# under the License.
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
diff --git a/tempest/tests/boto/test_ec2_volumes.py b/tempest/tests/boto/test_ec2_volumes.py
index ee7fa3f..7397cdb 100644
--- a/tempest/tests/boto/test_ec2_volumes.py
+++ b/tempest/tests/boto/test_ec2_volumes.py
@@ -19,7 +19,7 @@
import time
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.testboto import BotoTestCase
diff --git a/tempest/tests/boto/test_s3_buckets.py b/tempest/tests/boto/test_s3_buckets.py
index beed28b..36aa319 100644
--- a/tempest/tests/boto/test_s3_buckets.py
+++ b/tempest/tests/boto/test_s3_buckets.py
@@ -16,7 +16,7 @@
# under the License.
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
@@ -33,7 +33,7 @@
cls.client = cls.os.s3_client
cls.config = cls.os.config
- @unittest.skip("Skipped until the Bug #1076965 is resolved")
+ @testtools.skip("Skipped until the Bug #1076965 is resolved")
@attr(type='smoke')
def test_create_and_get_delete_bucket(self):
# S3 Create, get and delete bucket
diff --git a/tempest/tests/boto/test_s3_ec2_images.py b/tempest/tests/boto/test_s3_ec2_images.py
index f14115a..e0dc124 100644
--- a/tempest/tests/boto/test_s3_ec2_images.py
+++ b/tempest/tests/boto/test_s3_ec2_images.py
@@ -19,9 +19,8 @@
import os
from boto.s3.key import Key
-import nose
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
@@ -38,8 +37,8 @@
def setUpClass(cls):
super(S3ImagesTest, cls).setUpClass()
if not tempest.tests.boto.A_I_IMAGES_READY:
- raise nose.SkipTest("".join(("EC2 ", cls.__name__,
- ": requires ami/aki/ari manifest")))
+ raise cls.skipException("".join(("EC2 ", cls.__name__,
+ ": requires ami/aki/ari manifest")))
cls.os = clients.Manager()
cls.s3_client = cls.os.s3_client
cls.images_client = cls.os.ec2api_client
@@ -88,7 +87,7 @@
#TODO(afazekas): double deregister ?
self.cancelResourceCleanUp(image["cleanUp"])
- @unittest.skip("Skipped until the Bug #1074904 is resolved")
+ @testtools.skip("Skipped until the Bug #1074904 is resolved")
def test_register_get_deregister_aki_image(self):
# Register and deregister aki image
image = {"name": rand_name("aki-name-"),
@@ -116,7 +115,7 @@
self.assertIn(retrieved_image.state, self.valid_image_state)
self.cancelResourceCleanUp(image["cleanUp"])
- @unittest.skip("Skipped until the Bug #1074908 and #1074904 is resolved")
+ @testtools.skip("Skipped until the Bug #1074908 and #1074904 is resolved")
def test_register_get_deregister_ari_image(self):
# Register and deregister ari image
image = {"name": rand_name("ari-name-"),
diff --git a/tempest/tests/boto/test_s3_objects.py b/tempest/tests/boto/test_s3_objects.py
index 6e89539..cacd99f 100644
--- a/tempest/tests/boto/test_s3_objects.py
+++ b/tempest/tests/boto/test_s3_objects.py
@@ -19,7 +19,7 @@
from boto.s3.key import Key
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
@@ -37,7 +37,7 @@
cls.client = cls.os.s3_client
cls.config = cls.os.config
- @unittest.skip("Skipped until the Bug #1076534 is resolved")
+ @testtools.skip("Skipped until the Bug #1076534 is resolved")
@attr(type='smoke')
def test_create_get_delete_object(self):
# S3 Create, get and delete object
diff --git a/tempest/tests/boto/utils/wait.py b/tempest/tests/boto/utils/wait.py
index 77fe037..c2d4ea3 100644
--- a/tempest/tests/boto/utils/wait.py
+++ b/tempest/tests/boto/utils/wait.py
@@ -20,7 +20,7 @@
import time
from boto.exception import BotoServerError
-from unittest2 import TestCase
+from testtools import TestCase
import tempest.config
diff --git a/tempest/tests/compute/__init__.py b/tempest/tests/compute/__init__.py
index 398f982..08e5091 100644
--- a/tempest/tests/compute/__init__.py
+++ b/tempest/tests/compute/__init__.py
@@ -17,11 +17,11 @@
import logging
-import nose
from tempest import clients
from tempest import config
from tempest.exceptions import InvalidConfiguration
+from testresources import TestResourceManager
LOG = logging.getLogger(__name__)
@@ -80,3 +80,8 @@
% (user2_tenant_name, user2_password))
raise InvalidConfiguration(msg)
MULTI_USER = True
+
+
+class ComputeResource(TestResourceManager):
+ def make(self, dependency_resources=None):
+ return generic_setup_package()
diff --git a/tempest/tests/compute/admin/test_flavors.py b/tempest/tests/compute/admin/test_flavors.py
index 4859308..eb2392c 100644
--- a/tempest/tests/compute/admin/test_flavors.py
+++ b/tempest/tests/compute/admin/test_flavors.py
@@ -15,9 +15,8 @@
# License for the specific language governing permissions and limitations
# under the License.
-import nose
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest.common.utils.data_utils import rand_int_id
from tempest.common.utils.data_utils import rand_name
@@ -35,7 +34,7 @@
def setUpClass(self, cls):
if not compute.FLAVOR_EXTRA_DATA_ENABLED:
msg = "FlavorExtraData extension not enabled."
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
cls.client = cls.os.flavors_client
cls.flavor_name_prefix = 'test_flavor_'
diff --git a/tempest/tests/compute/admin/test_quotas.py b/tempest/tests/compute/admin/test_quotas.py
index 2c2e5da..b2b515a 100644
--- a/tempest/tests/compute/admin/test_quotas.py
+++ b/tempest/tests/compute/admin/test_quotas.py
@@ -18,23 +18,21 @@
from nose.plugins.attrib import attr
from tempest import exceptions
-from tempest.services.compute.admin.json import quotas_client as adm_quotas
-from tempest.tests.compute.base import BaseComputeTest
+from tempest.services.compute.admin.json \
+ import quotas_client as adm_quotas_json
+from tempest.services.compute.admin.xml import quotas_client as adm_quotas_xml
+from tempest.tests import compute
+from tempest.tests.compute import base
-class QuotasTest(BaseComputeTest):
+class QuotasAdminTestBase(object):
@classmethod
def setUpClass(cls):
- super(QuotasTest, cls).setUpClass()
- c_adm_user = cls.config.compute_admin.username
- c_adm_pass = cls.config.compute_admin.password
- c_adm_tenant = cls.config.compute_admin.tenant_name
- auth_url = cls.config.identity.uri
-
- cls.adm_client = adm_quotas.AdminQuotasClient(cls.config, c_adm_user,
- c_adm_pass, auth_url,
- c_adm_tenant)
+ cls.c_adm_user = cls.config.compute_admin.username
+ cls.c_adm_pass = cls.config.compute_admin.password
+ cls.c_adm_tenant = cls.config.compute_admin.tenant_name
+ cls.auth_url = cls.config.identity.uri
cls.client = cls.os.quotas_client
cls.identity_admin_client = cls._get_identity_admin_client()
resp, tenants = cls.identity_admin_client.list_tenants()
@@ -57,7 +55,7 @@
'cores': 20, 'security_groups': 10}
@classmethod
- def tearDown(cls):
+ def tearDownClass(cls):
for server in cls.servers:
try:
cls.servers_client.delete_server(server['id'])
@@ -154,3 +152,43 @@
finally:
self.adm_client.update_quota_set(self.demo_tenant_id,
ram=default_mem_quota)
+
+
+class QuotasAdminTestJSON(QuotasAdminTestBase, base.BaseComputeAdminTestJSON,
+ base.BaseComputeTest):
+
+ @classmethod
+ def setUpClass(cls):
+ base.BaseComputeAdminTestJSON.setUpClass()
+ base.BaseComputeTest.setUpClass()
+ super(QuotasAdminTestJSON, cls).setUpClass()
+
+ cls.adm_client = adm_quotas_json.AdminQuotasClientJSON(
+ cls.config, cls.c_adm_user, cls.c_adm_pass,
+ cls.auth_url, cls.c_adm_tenant)
+
+ @classmethod
+ def tearDownClass(cls):
+ super(QuotasAdminTestJSON, cls).tearDownClass()
+ base.BaseComputeTest.tearDownClass()
+
+
+class QuotasAdminTestXML(QuotasAdminTestBase, base.BaseComputeAdminTestXML,
+ base.BaseComputeTest):
+
+ @classmethod
+ def setUpClass(cls):
+ base.BaseComputeAdminTestXML.setUpClass()
+ base.BaseComputeTest.setUpClass()
+ super(QuotasAdminTestXML, cls).setUpClass()
+
+ cls.adm_client = adm_quotas_xml.AdminQuotasClientXML(cls.config,
+ cls.c_adm_user,
+ cls.c_adm_pass,
+ cls.auth_url,
+ cls.c_adm_tenant)
+
+ @classmethod
+ def tearDownClass(cls):
+ super(QuotasAdminTestXML, cls).tearDownClass()
+ base.BaseComputeTest.tearDownClass()
diff --git a/tempest/tests/compute/base.py b/tempest/tests/compute/base.py
index 9e2e883..2312931 100644
--- a/tempest/tests/compute/base.py
+++ b/tempest/tests/compute/base.py
@@ -18,9 +18,8 @@
import logging
import time
-import nose
import testresources
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
@@ -34,12 +33,11 @@
LOG = logging.getLogger(__name__)
-class BaseCompTest(unittest.TestCase,
+class BaseCompTest(testtools.TestCase,
testresources.ResourcedTestCase):
-
"""Base test case class for all Compute API tests."""
- resources = [('compute_init', compute.generic_setup_package())]
+ resources = [('compute_init', compute.ComputeResource())]
@classmethod
def setUpClass(cls):
@@ -249,7 +247,7 @@
super(BaseComputeTestXML, cls).setUpClass()
-class BaseComputeAdminTest(unittest.TestCase):
+class BaseComputeAdminTest(testtools.TestCase):
"""Base test case class for all Compute Admin API tests."""
@@ -263,7 +261,7 @@
if not cls.admin_username and cls.admin_password and cls.admin_tenant:
msg = ("Missing Compute Admin API credentials "
"in configuration.")
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
cls.os = clients.ComputeAdminManager(interface=cls._interface)
diff --git a/tempest/tests/compute/floating_ips/test_floating_ips_actions.py b/tempest/tests/compute/floating_ips/test_floating_ips_actions.py
index 9a9914a..59faf66 100644
--- a/tempest/tests/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/tests/compute/floating_ips/test_floating_ips_actions.py
@@ -16,7 +16,7 @@
# under the License.
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
diff --git a/tempest/tests/compute/floating_ips/test_list_floating_ips.py b/tempest/tests/compute/floating_ips/test_list_floating_ips.py
index 9eec27c..ea99e89 100644
--- a/tempest/tests/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/tests/compute/floating_ips/test_list_floating_ips.py
@@ -16,7 +16,7 @@
# under the License.
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
diff --git a/tempest/tests/compute/images/test_image_metadata.py b/tempest/tests/compute/images/test_image_metadata.py
index cdf4249..94bdca7 100644
--- a/tempest/tests/compute/images/test_image_metadata.py
+++ b/tempest/tests/compute/images/test_image_metadata.py
@@ -53,6 +53,7 @@
super(ImagesMetadataTest, cls).tearDownClass()
def setUp(self):
+ super(ImagesMetadataTest, self).setUp()
meta = {'key1': 'value1', 'key2': 'value2'}
resp, _ = self.client.set_image_metadata(self.image_id, meta)
self.assertEqual(resp.status, 200)
diff --git a/tempest/tests/compute/images/test_images.py b/tempest/tests/compute/images/test_images.py
index 2557f16..1fc03b8 100644
--- a/tempest/tests/compute/images/test_images.py
+++ b/tempest/tests/compute/images/test_images.py
@@ -15,9 +15,8 @@
# License for the specific language governing permissions and limitations
# under the License.
-import nose
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import parse_image_id
@@ -113,7 +112,7 @@
self.assertRaises(exceptions.Duplicate, self.client.create_image,
server['id'], snapshot_name)
- @unittest.skip("Until Bug 1039739 is fixed")
+ @testtools.skip("Until Bug 1039739 is fixed")
@attr(type='negative')
def test_create_image_when_server_is_rebooting(self):
# Return error when creating an image of server that is rebooting
@@ -217,6 +216,7 @@
ImagesTestBase):
def tearDown(self):
ImagesTestBase.tearDown(self)
+ base.BaseComputeTestJSON.tearDown(self)
@classmethod
def setUpClass(cls):
@@ -243,6 +243,7 @@
ImagesTestBase):
def tearDown(self):
ImagesTestBase.tearDown(self)
+ base.BaseComputeTestXML.tearDown(self)
@classmethod
def setUpClass(cls):
diff --git a/tempest/tests/compute/images/test_images_oneserver.py b/tempest/tests/compute/images/test_images_oneserver.py
index f8b560b..f3b1e01 100644
--- a/tempest/tests/compute/images/test_images_oneserver.py
+++ b/tempest/tests/compute/images/test_images_oneserver.py
@@ -15,9 +15,8 @@
# License for the specific language governing permissions and limitations
# under the License.
-import nose
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import parse_image_id
@@ -43,7 +42,7 @@
self.image_ids.remove(image_id)
@attr(type='negative')
- @unittest.skip("Until Bug 1006725 is fixed")
+ @testtools.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:
@@ -56,7 +55,7 @@
" are used for image name")
@attr(type='negative')
- @unittest.skip("Until Bug 1005423 is fixed")
+ @testtools.skip("Until Bug 1005423 is fixed")
def test_create_image_specify_invalid_metadata(self):
# Return an error when creating image with invalid metadata
try:
@@ -69,7 +68,7 @@
self.fail("Should raise 400 Bad Request if meta data is invalid")
@attr(type='negative')
- @unittest.skip("Until Bug 1005423 is fixed")
+ @testtools.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:
@@ -82,8 +81,8 @@
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.')
+ @testtools.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')
@@ -99,8 +98,8 @@
self.alt_client.delete_image, image_id)
@attr(type='smoke')
- @unittest.skipUnless(compute.CREATE_IMAGE_ENABLED,
- 'Environment unable to create images.')
+ @testtools.skipUnless(compute.CREATE_IMAGE_ENABLED,
+ 'Environment unable to create images.')
def test_create_delete_image(self):
# Create a new image
@@ -123,8 +122,8 @@
self.assertEqual(original_image['minDisk'], image['minDisk'])
@attr(type='negative')
- @unittest.skipUnless(compute.MULTI_USER,
- 'Need multiple users for this test.')
+ @testtools.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
@@ -157,7 +156,7 @@
"of the server is still being saved")
@attr(type='negative')
- @unittest.skip("Until Bug 1004564 is fixed")
+ @testtools.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
@@ -192,6 +191,7 @@
def tearDown(self):
ImagesOneServerTestBase.tearDown(self)
+ base.BaseComputeTestJSON.tearDown(self)
@classmethod
def setUpClass(cls):
@@ -220,6 +220,7 @@
def tearDown(self):
ImagesOneServerTestBase.tearDown(self)
+ base.BaseComputeTestXML.tearDown(self)
@classmethod
def setUpClass(cls):
diff --git a/tempest/tests/compute/images/test_images_whitebox.py b/tempest/tests/compute/images/test_images_whitebox.py
index 2987534..b2419b4 100644
--- a/tempest/tests/compute/images/test_images_whitebox.py
+++ b/tempest/tests/compute/images/test_images_whitebox.py
@@ -50,7 +50,7 @@
cls.image_ids.remove(image_id)
@classmethod
- def update_state(self, server_id, vm_state, task_state, deleted=False):
+ def update_state(self, server_id, vm_state, task_state, deleted=0):
"""Update states of an instance in database for validation."""
if not task_state:
task_state = "NULL"
@@ -63,7 +63,7 @@
self.connection.execute(stmt, autocommit=True)
- def _test_create_image_409_base(self, vm_state, task_state, deleted=False):
+ def _test_create_image_409_base(self, vm_state, task_state, deleted=0):
"""Base method for create image tests based on vm and task states."""
try:
self.update_state(self.shared_server['id'], vm_state,
diff --git a/tempest/tests/compute/keypairs/test_keypairs.py b/tempest/tests/compute/keypairs/test_keypairs.py
index 7d95a9b..45c9079 100644
--- a/tempest/tests/compute/keypairs/test_keypairs.py
+++ b/tempest/tests/compute/keypairs/test_keypairs.py
@@ -16,7 +16,7 @@
# under the License.
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
@@ -77,7 +77,7 @@
self.assertEqual(202, resp.status)
@attr(type='positive')
- @unittest.skip("Skipped until the Bug #980688 is resolved")
+ @testtools.skip("Skipped until the Bug #980688 is resolved")
def test_get_keypair_detail(self):
# Keypair should be created, Got details by name and deleted
k_name = rand_name('keypair-')
@@ -137,7 +137,7 @@
self.fail('Expected BadRequest for invalid public key')
@attr(type='negative')
- @unittest.skip("Skipped until the Bug #1086980 is resolved")
+ @testtools.skip("Skipped until the Bug #1086980 is resolved")
def test_keypair_delete_nonexistant_key(self):
# Non-existant key deletion should throw a proper error
k_name = rand_name("keypair-non-existant-")
diff --git a/tempest/tests/compute/limits/test_absolute_limits.py b/tempest/tests/compute/limits/test_absolute_limits.py
index 89c5b25..d520b92 100644
--- a/tempest/tests/compute/limits/test_absolute_limits.py
+++ b/tempest/tests/compute/limits/test_absolute_limits.py
@@ -15,7 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import unittest2 as unittest
+import testtools
from tempest.tests.compute import base
@@ -26,7 +26,7 @@
def setUpClass(cls):
cls.client = cls.limits_client
- @unittest.skip("Skipped until the Bug #1025294 is resolved")
+ @testtools.skip("Skipped until the Bug #1025294 is resolved")
def test_absLimits_get(self):
# To check if all limits are present in the response
resp, absolute_limits = self.client.get_absolute_limits()
diff --git a/tempest/tests/compute/servers/test_console_output.py b/tempest/tests/compute/servers/test_console_output.py
index 3ad29a1..b26220b 100644
--- a/tempest/tests/compute/servers/test_console_output.py
+++ b/tempest/tests/compute/servers/test_console_output.py
@@ -16,7 +16,7 @@
# under the License.
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
@@ -63,7 +63,7 @@
pass
@attr(type='positive')
- @unittest.skip('Until tempest bug 1014683 is fixed.')
+ @testtools.skip('Until tempest bug 1014683 is fixed.')
def test_get_console_output_server_id_in_reboot_status(self):
# Positive test:Should be able to GET the console output
# for a given server_id in reboot status
diff --git a/tempest/tests/compute/servers/test_create_server.py b/tempest/tests/compute/servers/test_create_server.py
index c5a54dc..0dcc79f 100644
--- a/tempest/tests/compute/servers/test_create_server.py
+++ b/tempest/tests/compute/servers/test_create_server.py
@@ -16,10 +16,9 @@
# under the License.
import base64
-import nose
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest.common.utils.data_utils import rand_name
@@ -98,14 +97,14 @@
self.assertTrue(found)
@attr(type='positive')
- @unittest.skipIf(not run_ssh, 'Instance validation tests are disabled.')
+ @testtools.skipIf(not run_ssh, 'Instance validation tests are disabled.')
def test_can_log_into_created_server(self):
# Check that the user can authenticate with the generated password
linux_client = RemoteClient(self.server, self.ssh_user, self.password)
self.assertTrue(linux_client.can_authenticate())
@attr(type='positive')
- @unittest.skipIf(not run_ssh, 'Instance validation tests are disabled.')
+ @testtools.skipIf(not run_ssh, 'Instance validation tests are disabled.')
def test_verify_created_server_vcpus(self):
# Verify that the number of vcpus reported by the instance matches
# the amount stated by the flavor
@@ -114,7 +113,7 @@
self.assertEqual(flavor['vcpus'], linux_client.get_number_of_vcpus())
@attr(type='positive')
- @unittest.skipIf(not run_ssh, 'Instance validation tests are disabled.')
+ @testtools.skipIf(not run_ssh, 'Instance validation tests are disabled.')
def test_host_name_is_same_as_server_name(self):
# Verify the instance host name is the same as the server name
linux_client = RemoteClient(self.server, self.ssh_user, self.password)
@@ -128,7 +127,7 @@
def setUpClass(cls):
if not compute.DISK_CONFIG_ENABLED:
msg = "DiskConfig extension not enabled."
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
super(ServersTestAutoDisk, cls).setUpClass()
cls.disk_config = 'AUTO'
ServersTest.setUpClass(cls)
@@ -146,7 +145,7 @@
def setUpClass(cls):
if not compute.DISK_CONFIG_ENABLED:
msg = "DiskConfig extension not enabled."
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
super(ServersTestManualDisk, cls).setUpClass()
cls.disk_config = 'MANUAL'
ServersTest.setUpClass(cls)
diff --git a/tempest/tests/compute/servers/test_disk_config.py b/tempest/tests/compute/servers/test_disk_config.py
index 490156b..c3a37ff 100644
--- a/tempest/tests/compute/servers/test_disk_config.py
+++ b/tempest/tests/compute/servers/test_disk_config.py
@@ -15,9 +15,8 @@
# License for the specific language governing permissions and limitations
# under the License.
-import nose
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
@@ -31,7 +30,7 @@
def setUpClass(cls):
if not compute.DISK_CONFIG_ENABLED:
msg = "DiskConfig extension not enabled."
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
super(TestServerDiskConfig, cls).setUpClass()
cls.client = cls.os.servers_client
@@ -96,7 +95,7 @@
resp, body = self.client.delete_server(server['id'])
@attr(type='positive')
- @unittest.skipUnless(compute.RESIZE_AVAILABLE, 'Resize not available.')
+ @testtools.skipUnless(compute.RESIZE_AVAILABLE, 'Resize not available.')
def test_resize_server_from_manual_to_auto(self):
# A server should be resized from manual to auto disk config
name = rand_name('server')
@@ -122,7 +121,7 @@
resp, body = self.client.delete_server(server['id'])
@attr(type='positive')
- @unittest.skipUnless(compute.RESIZE_AVAILABLE, 'Resize not available.')
+ @testtools.skipUnless(compute.RESIZE_AVAILABLE, 'Resize not available.')
def test_resize_server_from_auto_to_manual(self):
# A server should be resized from auto to manual disk config
name = rand_name('server')
diff --git a/tempest/tests/compute/servers/test_list_server_filters.py b/tempest/tests/compute/servers/test_list_server_filters.py
index d943e5d..45ea3a0 100644
--- a/tempest/tests/compute/servers/test_list_server_filters.py
+++ b/tempest/tests/compute/servers/test_list_server_filters.py
@@ -16,10 +16,8 @@
# under the License.
-import nose
from nose.plugins.attrib import attr
-import nose.plugins.skip
-import unittest2 as unittest
+import testtools
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
diff --git a/tempest/tests/compute/servers/test_list_servers_negative.py b/tempest/tests/compute/servers/test_list_servers_negative.py
index 035ffe8..eb4ea02 100644
--- a/tempest/tests/compute/servers/test_list_servers_negative.py
+++ b/tempest/tests/compute/servers/test_list_servers_negative.py
@@ -18,8 +18,7 @@
import re
import sys
-import nose
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
@@ -64,7 +63,7 @@
tenant_name = cls.os.tenant_name
msg = ("User/tenant %(username)s/%(tenant_name)s already have "
"existing server instances. Skipping test.") % locals()
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
resp, body = cls.alt_client.list_servers()
servers = body['servers']
@@ -74,7 +73,7 @@
tenant_name = cls.alt_manager.tenant_name
msg = ("Alt User/tenant %(username)s/%(tenant_name)s already have "
"existing server instances. Skipping test.") % locals()
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
# The following servers are created for use
# by the test methods in this class. These
diff --git a/tempest/tests/compute/servers/test_server_actions.py b/tempest/tests/compute/servers/test_server_actions.py
index 2fe8464..fd35461 100644
--- a/tempest/tests/compute/servers/test_server_actions.py
+++ b/tempest/tests/compute/servers/test_server_actions.py
@@ -19,7 +19,7 @@
import time
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest.common.utils.data_utils import rand_name
from tempest.common.utils.linux.remote_client import RemoteClient
@@ -35,8 +35,8 @@
run_ssh = tempest.config.TempestConfig().compute.run_ssh
@attr(type='smoke')
- @unittest.skipUnless(compute.CHANGE_PASSWORD_AVAILABLE,
- 'Change password not available.')
+ @testtools.skipUnless(compute.CHANGE_PASSWORD_AVAILABLE,
+ 'Change password not available.')
def test_change_server_password(self):
# The server's password should be set to the provided password
new_password = 'Newpass1234'
@@ -70,7 +70,7 @@
self.assertGreater(new_boot_time, boot_time)
@attr(type='smoke')
- @unittest.skip('Until bug 1014647 is dealt with.')
+ @testtools.skip('Until bug 1014647 is dealt with.')
def test_reboot_server_soft(self):
# The server should be signaled to reboot gracefully
if self.run_ssh:
@@ -123,7 +123,7 @@
self.assertTrue(linux_client.can_authenticate())
@attr(type='smoke')
- @unittest.skipIf(not resize_available, 'Resize not available.')
+ @testtools.skipIf(not resize_available, 'Resize not available.')
def test_resize_server_confirm(self):
# The server's RAM and disk space should be modified to that of
# the provided flavor
@@ -139,7 +139,7 @@
self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
@attr(type='positive')
- @unittest.skipIf(not resize_available, 'Resize not available.')
+ @testtools.skipIf(not resize_available, 'Resize not available.')
def test_resize_server_revert(self):
# The server's RAM and disk space should return to its original
# values after a resize is reverted
diff --git a/tempest/tests/compute/servers/test_server_advanced_ops.py b/tempest/tests/compute/servers/test_server_advanced_ops.py
index 4e85b04..f949f2e 100644
--- a/tempest/tests/compute/servers/test_server_advanced_ops.py
+++ b/tempest/tests/compute/servers/test_server_advanced_ops.py
@@ -17,7 +17,6 @@
import logging
-import nose
from tempest.common.utils.data_utils import rand_name
from tempest import test
@@ -39,13 +38,13 @@
if not cls.config.compute.resize_available:
msg = "Skipping test - resize not available on this host"
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
resize_flavor = cls.config.compute.flavor_ref_alt
if resize_flavor == cls.config.compute.flavor_ref:
msg = "Skipping test - flavor_ref and flavor_ref_alt are identical"
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
@classmethod
def tearDownClass(cls):
diff --git a/tempest/tests/compute/servers/test_server_metadata.py b/tempest/tests/compute/servers/test_server_metadata.py
index 6c44c3c..7db963e 100644
--- a/tempest/tests/compute/servers/test_server_metadata.py
+++ b/tempest/tests/compute/servers/test_server_metadata.py
@@ -44,6 +44,7 @@
super(ServerMetadataTest, cls).tearDownClass()
def setUp(self):
+ super(ServerMetadataTest, self).setUp()
meta = {'key1': 'value1', 'key2': 'value2'}
resp, _ = self.client.set_server_metadata(self.server_id, meta)
self.assertEqual(resp.status, 200)
diff --git a/tempest/tests/compute/servers/test_servers.py b/tempest/tests/compute/servers/test_servers.py
index 8054c1f..e0d4d44 100644
--- a/tempest/tests/compute/servers/test_servers.py
+++ b/tempest/tests/compute/servers/test_servers.py
@@ -168,7 +168,6 @@
# deletes are running slow we could very well overrun system
# memory
self.clear_servers()
-
super(ServersTestJSON, self).tearDown()
@@ -184,5 +183,4 @@
# deletes are running slow we could very well overrun system
# memory
self.clear_servers()
-
super(ServersTestXML, self).tearDown()
diff --git a/tempest/tests/compute/servers/test_servers_negative.py b/tempest/tests/compute/servers/test_servers_negative.py
index f7624b3..ea63360 100644
--- a/tempest/tests/compute/servers/test_servers_negative.py
+++ b/tempest/tests/compute/servers/test_servers_negative.py
@@ -17,9 +17,8 @@
import sys
-import nose
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
@@ -31,7 +30,7 @@
@classmethod
def setUpClass(cls):
- raise nose.SkipTest("Until Bug 1046870 is fixed")
+ raise cls.skipException("Until Bug 1046870 is fixed")
super(ServersNegativeTest, cls).setUpClass()
cls.client = cls.servers_client
cls.img_client = cls.images_client
diff --git a/tempest/tests/compute/servers/test_servers_whitebox.py b/tempest/tests/compute/servers/test_servers_whitebox.py
index 33519b0..502f16b 100644
--- a/tempest/tests/compute/servers/test_servers_whitebox.py
+++ b/tempest/tests/compute/servers/test_servers_whitebox.py
@@ -15,7 +15,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import nose
from nose.plugins.attrib import attr
from tempest import exceptions
@@ -28,7 +27,7 @@
@classmethod
def setUpClass(cls):
- raise nose.SkipTest("Until Bug 1034129 is fixed")
+ raise cls.skipException("Until Bug 1034129 is fixed")
super(ServersWhiteboxTest, cls).setUpClass()
BaseIdentityAdminTest.setUpClass()
cls.client = cls.servers_client
diff --git a/tempest/tests/compute/test_authorization.py b/tempest/tests/compute/test_authorization.py
index 78661d1..4d3b553 100644
--- a/tempest/tests/compute/test_authorization.py
+++ b/tempest/tests/compute/test_authorization.py
@@ -16,9 +16,8 @@
# under the License.
from nose.plugins.attrib import attr
-from nose import SkipTest
from nose.tools import raises
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import parse_image_id
@@ -34,7 +33,7 @@
def setUpClass(cls):
if not compute.MULTI_USER:
msg = "Need >1 user"
- raise SkipTest(msg)
+ raise cls.skipException(msg)
super(AuthorizationTest, cls).setUpClass()
@@ -225,7 +224,7 @@
@raises(exceptions.NotFound)
@attr(type='negative')
- @unittest.skip("Skipped until the Bug #1086980 is resolved")
+ @testtools.skip("Skipped until the Bug #1086980 is resolved")
def test_delete_keypair_of_alt_account_fails(self):
# A DELETE request for another user's keypair should fail
self.alt_keypairs_client.delete_keypair(self.keypairname)
diff --git a/tempest/tests/compute/test_live_block_migration.py b/tempest/tests/compute/test_live_block_migration.py
index eceaaba..1b651ab 100644
--- a/tempest/tests/compute/test_live_block_migration.py
+++ b/tempest/tests/compute/test_live_block_migration.py
@@ -18,9 +18,8 @@
import random
import string
-import nose
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest.common.utils.linux.remote_client import RemoteClient
from tempest import config
@@ -101,12 +100,12 @@
return server_id
@attr(type='positive')
- @unittest.skipIf(not live_migration_available,
- 'Block Live migration not available')
+ @testtools.skipIf(not live_migration_available,
+ 'Block Live migration not available')
def test_001_live_block_migration(self):
# Live block migrate an instance to another host
if len(self._get_compute_hostnames()) < 2:
- raise nose.SkipTest(
+ raise self.skipTest(
"Less than 2 compute nodes, skipping migration test.")
server_id = self._get_an_active_server()
actual_host = self._get_host_for_server(server_id)
@@ -116,9 +115,9 @@
self.assertEquals(target_host, self._get_host_for_server(server_id))
@attr(type='positive', bug='lp1051881')
- @unittest.skip('Until bug 1051881 is dealt with.')
- @unittest.skipIf(not live_migration_available,
- 'Block Live migration not available')
+ @testtools.skip('Until bug 1051881 is dealt with.')
+ @testtools.skipIf(not live_migration_available,
+ 'Block Live migration not available')
def test_002_invalid_host_for_migration(self):
# Migrating to an invalid host should not change the status
diff --git a/tempest/tests/compute/test_quotas.py b/tempest/tests/compute/test_quotas.py
index 3dc2515..9306351 100644
--- a/tempest/tests/compute/test_quotas.py
+++ b/tempest/tests/compute/test_quotas.py
@@ -17,14 +17,13 @@
from nose.plugins.attrib import attr
-from tempest.tests.compute.base import BaseComputeTest
+from tempest.tests.compute import base
-class QuotasTest(BaseComputeTest):
+class QuotasTestBase(object):
@classmethod
def setUpClass(cls):
- super(QuotasTest, cls).setUpClass()
cls.client = cls.quotas_client
cls.admin_client = cls._get_identity_admin_client()
resp, tenants = cls.admin_client.list_tenants()
@@ -47,3 +46,19 @@
self.assertSequenceEqual(expected_quota_set, quota_set)
except Exception:
self.fail("Quota set for tenant did not have default limits")
+
+
+class QuotasTestJSON(QuotasTestBase, base.BaseComputeTestJSON):
+
+ @classmethod
+ def setUpClass(cls):
+ base.BaseComputeTestJSON.setUpClass()
+ super(QuotasTestJSON, cls).setUpClass()
+
+
+class QuotasTestXML(QuotasTestBase, base.BaseComputeTestXML):
+
+ @classmethod
+ def setUpClass(cls):
+ base.BaseComputeTestXML.setUpClass()
+ super(QuotasTestXML, cls).setUpClass()
diff --git a/tempest/tests/compute/volumes/test_attach_volume.py b/tempest/tests/compute/volumes/test_attach_volume.py
index 9581026..0e0e4a5 100644
--- a/tempest/tests/compute/volumes/test_attach_volume.py
+++ b/tempest/tests/compute/volumes/test_attach_volume.py
@@ -16,7 +16,7 @@
# under the License.
from nose.plugins.attrib import attr
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
@@ -68,7 +68,7 @@
return server, volume
@attr(type='positive')
- @unittest.skipIf(not run_ssh, 'SSH required for this test')
+ @testtools.skipIf(not run_ssh, 'SSH required for this test')
def test_attach_detach_volume(self):
# Stop and Start a server with an attached volume, ensuring that
# the volume remains attached.
diff --git a/tempest/tests/compute/volumes/test_volumes_list.py b/tempest/tests/compute/volumes/test_volumes_list.py
index fef9c8d..cc690a5 100644
--- a/tempest/tests/compute/volumes/test_volumes_list.py
+++ b/tempest/tests/compute/volumes/test_volumes_list.py
@@ -15,7 +15,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import nose
from tempest.common.utils.data_utils import rand_name
from tempest.tests.compute import base
@@ -96,7 +95,7 @@
"test. This typically means that the backing file "
"size of the nova-volumes group is too small to "
"create the 3 volumes needed by this test case")
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
raise
@classmethod
@@ -142,7 +141,7 @@
"test. This typically means that the backing file "
"size of the nova-volumes group is too small to "
"create the 3 volumes needed by this test case")
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
raise
@classmethod
diff --git a/tempest/tests/identity/admin/test_roles.py b/tempest/tests/identity/admin/test_roles.py
index f0dd8d9..2779b51 100644
--- a/tempest/tests/identity/admin/test_roles.py
+++ b/tempest/tests/identity/admin/test_roles.py
@@ -15,7 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import unittest2 as unittest
+import testtools
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
diff --git a/tempest/tests/identity/admin/test_services.py b/tempest/tests/identity/admin/test_services.py
index 30dfeb0..5261b9d 100644
--- a/tempest/tests/identity/admin/test_services.py
+++ b/tempest/tests/identity/admin/test_services.py
@@ -15,7 +15,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import nose
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
@@ -76,4 +75,4 @@
@classmethod
def setUpClass(cls):
super(ServicesTestXML, cls).setUpClass()
- raise nose.SkipTest("Skipping until Bug #1061738 resolved")
+ raise cls.skipException("Skipping until Bug #1061738 resolved")
diff --git a/tempest/tests/identity/admin/test_tenants.py b/tempest/tests/identity/admin/test_tenants.py
index 578af4a..54383f1 100644
--- a/tempest/tests/identity/admin/test_tenants.py
+++ b/tempest/tests/identity/admin/test_tenants.py
@@ -15,7 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import unittest2 as unittest
+import testtools
from nose.plugins.attrib import attr
from tempest.common.utils.data_utils import rand_name
diff --git a/tempest/tests/identity/admin/test_users.py b/tempest/tests/identity/admin/test_users.py
index 7ad932b..ef7d934 100644
--- a/tempest/tests/identity/admin/test_users.py
+++ b/tempest/tests/identity/admin/test_users.py
@@ -16,11 +16,11 @@
# under the License.
from nose.plugins.attrib import attr
-import unittest2 as unittest
-
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
from tempest.tests.identity import base
+import testtools
+from testtools.matchers._basic import Contains
class UsersTestBase(object):
@@ -76,7 +76,7 @@
self.data.tenant['id'], self.data.test_email)
@attr(type='negative')
- @unittest.skip("Until Bug 999084 is fixed")
+ @testtools.skip("Until Bug 999084 is fixed")
def test_create_user_with_empty_password(self):
# User with an empty password should not be created
self.data.setup_test_tenant()
@@ -85,7 +85,7 @@
self.alt_email)
@attr(type='nagative')
- @unittest.skip("Until Bug 999084 is fixed")
+ @testtools.skip("Until Bug 999084 is fixed")
def test_create_user_with_long_password(self):
# User having password exceeding max length should not be created
self.data.setup_test_tenant()
@@ -94,7 +94,7 @@
self.alt_email)
@attr(type='negative')
- @unittest.skip("Until Bug 999084 is fixed")
+ @testtools.skip("Until Bug 999084 is fixed")
def test_create_user_with_invalid_email_format(self):
# Email format should be validated while creating a user
self.data.setup_test_tenant()
@@ -227,8 +227,9 @@
# Get a list of users and find the test user
self.data.setup_test_user()
resp, users = self.client.get_users()
- self.assertIn(self.data.test_user, [u['name'] for u in users],
- "Could not find %s" % self.data.test_user)
+ self.assertThat([u['name'] for u in users],
+ Contains(self.data.test_user),
+ "Could not find %s" % self.data.test_user)
@attr(type='negative')
def test_get_users_by_unauthorized_user(self):
diff --git a/tempest/tests/identity/base.py b/tempest/tests/identity/base.py
index 9c318cd..cbd943e 100644
--- a/tempest/tests/identity/base.py
+++ b/tempest/tests/identity/base.py
@@ -15,14 +15,13 @@
# License for the specific language governing permissions and limitations
# under the License.
-import nose
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
-class BaseIdAdminTest(unittest.TestCase):
+class BaseIdAdminTest(testtools.TestCase):
@classmethod
def setUpClass(cls):
@@ -31,7 +30,7 @@
cls.token_client = os.token_client
if not cls.client.has_admin_extensions():
- raise nose.SkipTest("Admin extensions disabled")
+ raise cls.skipException("Admin extensions disabled")
cls.data = DataGenerator(cls.client)
diff --git a/tempest/tests/image/test_images.py b/tempest/tests/image/test_images.py
index 2429a32..0a1a25f 100644
--- a/tempest/tests/image/test_images.py
+++ b/tempest/tests/image/test_images.py
@@ -18,10 +18,10 @@
import cStringIO as StringIO
import random
-import unittest2 as unittest
+import testtools
from nose.plugins.attrib import attr
-from nose.plugins.skip import SkipTest
+
GLANCE_INSTALLED = False
try:
@@ -33,7 +33,7 @@
from tempest import clients
-class CreateRegisterImagesTest(unittest.TestCase):
+class CreateRegisterImagesTest(testtools.TestCase):
"""
Here we test the registration and creation of images
@@ -42,7 +42,7 @@
@classmethod
def setUpClass(cls):
if not GLANCE_INSTALLED:
- raise SkipTest('Glance not installed')
+ raise cls.skipException('Glance not installed')
cls.os = clients.ServiceManager()
cls.client = cls.os.images.get_client()
cls.created_images = []
@@ -128,7 +128,7 @@
self.assertEqual('active', results.status)
-class ListImagesTest(unittest.TestCase):
+class ListImagesTest(testtools.TestCase):
"""
Here we test the listing of image information
@@ -137,7 +137,7 @@
@classmethod
def setUpClass(cls):
if not GLANCE_INSTALLED:
- raise SkipTest('Glance not installed')
+ raise cls.skipException('Glance not installed')
cls.os = clients.ServiceManager()
cls.client = cls.os.images.get_client()
cls.created_images = []
diff --git a/tempest/tests/network/base.py b/tempest/tests/network/base.py
index 90b351d..01330cc 100644
--- a/tempest/tests/network/base.py
+++ b/tempest/tests/network/base.py
@@ -15,15 +15,14 @@
# License for the specific language governing permissions and limitations
# under the License.
-import nose
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
-class BaseNetworkTest(unittest.TestCase):
+class BaseNetworkTest(testtools.TestCase):
@classmethod
def setUpClass(cls):
@@ -40,7 +39,7 @@
except exceptions.EndpointNotFound:
enabled = False
skip_msg = "No OpenStack Network API endpoint"
- raise nose.SkipTest(skip_msg)
+ raise cls.skipException(skip_msg)
@classmethod
def tearDownClass(cls):
diff --git a/tempest/tests/network/test_network_basic_ops.py b/tempest/tests/network/test_network_basic_ops.py
index 3c99f77..bdebced 100644
--- a/tempest/tests/network/test_network_basic_ops.py
+++ b/tempest/tests/network/test_network_basic_ops.py
@@ -19,7 +19,6 @@
import subprocess
import netaddr
-import nose
from quantumclient.common import exceptions as exc
@@ -179,7 +178,7 @@
cls.enabled = not bool(msg)
if msg:
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
@classmethod
def setUpClass(cls):
@@ -458,7 +457,7 @@
def test_005_create_servers(self):
if not (self.keypairs or self.security_groups or self.networks):
- raise nose.SkipTest('Necessary resources have not been defined')
+ raise self.skipTest('Necessary resources have not been defined')
for i, network in enumerate(self.networks):
tenant_id = network.tenant_id
name = rand_name('server-smoke-%d-' % i)
@@ -471,9 +470,9 @@
def test_006_check_tenant_network_connectivity(self):
if not self.config.network.tenant_networks_reachable:
msg = 'Tenant networks not configured to be reachable.'
- raise nose.SkipTest(msg)
+ raise self.skipTest(msg)
if not self.servers:
- raise nose.SkipTest("No VM's have been created")
+ raise self.skipTest("No VM's have been created")
for server in self.servers:
for net_name, ip_addresses in server.networks.iteritems():
for ip_address in ip_addresses:
@@ -484,9 +483,9 @@
def test_007_assign_floating_ips(self):
public_network_id = self.config.network.public_network_id
if not public_network_id:
- raise nose.SkipTest('Public network not configured')
+ raise self.skipTest('Public network not configured')
if not self.servers:
- raise nose.SkipTest("No VM's have been created")
+ raise self.skipTest("No VM's have been created")
for server in self.servers:
floating_ip = self._create_floating_ip(server, public_network_id)
self.floating_ips.setdefault(server, [])
@@ -494,7 +493,7 @@
def test_008_check_public_network_connectivity(self):
if not self.floating_ips:
- raise nose.SkipTest('No floating ips have been allocated.')
+ raise self.skipTest('No floating ips have been allocated.')
for server, floating_ips in self.floating_ips.iteritems():
for floating_ip in floating_ips:
ip_address = floating_ip.floating_ip_address
diff --git a/tempest/tests/object_storage/base.py b/tempest/tests/object_storage/base.py
index 5e3d0bc..8c32ffc 100644
--- a/tempest/tests/object_storage/base.py
+++ b/tempest/tests/object_storage/base.py
@@ -15,8 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import nose
-import unittest2 as unittest
+import testtools
from tempest import clients
import tempest.config
@@ -24,7 +23,7 @@
from tempest.tests.identity.base import DataGenerator
-class BaseObjectTest(unittest.TestCase):
+class BaseObjectTest(testtools.TestCase):
@classmethod
def setUpClass(cls):
@@ -50,4 +49,4 @@
except exceptions.EndpointNotFound:
enabled = False
skip_msg = "No OpenStack Object Storage API endpoint"
- raise nose.SkipTest(skip_msg)
+ raise cls.skipException(skip_msg)
diff --git a/tempest/tests/object_storage/test_container_sync.py b/tempest/tests/object_storage/test_container_sync.py
index 3dea259..597fd86 100644
--- a/tempest/tests/object_storage/test_container_sync.py
+++ b/tempest/tests/object_storage/test_container_sync.py
@@ -19,7 +19,7 @@
from tempest.common.utils.data_utils import arbitrary_string
from tempest.common.utils.data_utils import rand_name
from tempest.tests.object_storage import base
-import unittest2 as unittest
+import testtools
class ContainerSyncTest(base.BaseObjectTest):
@@ -61,7 +61,7 @@
#Attempt to delete the container
resp, _ = client[0].delete_container(cont_name)
- @unittest.skip('Until Bug 1093743 is resolved.')
+ @testtools.skip('Until Bug 1093743 is resolved.')
@attr(type='positive')
def test_container_synchronization(self):
#Container to container synchronization
diff --git a/tempest/tests/object_storage/test_object_expiry.py b/tempest/tests/object_storage/test_object_expiry.py
index 099fc16..8e6b23b 100644
--- a/tempest/tests/object_storage/test_object_expiry.py
+++ b/tempest/tests/object_storage/test_object_expiry.py
@@ -20,8 +20,8 @@
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
from tempest.tests.object_storage import base
+import testtools
from time import sleep
-import unittest2 as unittest
class ObjectExpiryTest(base.BaseObjectTest):
@@ -54,7 +54,7 @@
#Attempt to delete the container
resp, _ = cls.container_client.delete_container(cls.container_name)
- @unittest.skip('Until bug 1069849 is resolved.')
+ @testtools.skip('Until bug 1069849 is resolved.')
@attr(type='regression')
def test_get_object_after_expiry_time(self):
# GET object after expiry time
diff --git a/tempest/tests/object_storage/test_object_services.py b/tempest/tests/object_storage/test_object_services.py
index a65401c..d5b6d5c 100644
--- a/tempest/tests/object_storage/test_object_services.py
+++ b/tempest/tests/object_storage/test_object_services.py
@@ -21,8 +21,8 @@
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
from tempest.tests.object_storage import base
+import testtools
from time import time
-import unittest2 as unittest
class ObjectTest(base.BaseObjectTest):
@@ -327,7 +327,7 @@
self.assertIn('x-container-read', resp)
self.assertEqual(resp['x-container-read'], 'x')
- @unittest.skip('Until Bug 1091669 is resolved.')
+ @testtools.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
@@ -382,7 +382,7 @@
self.assertIn('x-container-read', resp)
self.assertEqual(resp['x-container-read'], 'x')
- @unittest.skip('Until Bug #1020722 is resolved.')
+ @testtools.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
@@ -433,7 +433,7 @@
self.assertIn('x-container-write', resp)
self.assertEqual(resp['x-container-write'], 'x')
- @unittest.skip('Until Bug #1020722 is resolved.')
+ @testtools.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
@@ -592,7 +592,7 @@
self.container_name, object_name,
metadata=self.custom_headers)
- @unittest.skip('Until bug 1097137 is resolved.')
+ @testtools.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
diff --git a/tempest/tests/utils.py b/tempest/tests/utils.py
index 571fc2a..0738201 100644
--- a/tempest/tests/utils.py
+++ b/tempest/tests/utils.py
@@ -17,41 +17,7 @@
"""Common utilities used in testing."""
-import nose.plugins.skip
-
-
-class skip_if(object):
- """Decorator that skips a test if condition is true."""
- def __init__(self, condition, msg):
- self.condition = condition
- self.message = msg
-
- def __call__(self, func):
- def _skipper(*args, **kw):
- """Wrapped skipper function."""
- if self.condition:
- raise nose.SkipTest(self.message)
- func(*args, **kw)
- _skipper.__name__ = func.__name__
- _skipper.__doc__ = func.__doc__
- return _skipper
-
-
-class skip_unless(object):
- """Decorator that skips a test if condition is not true."""
- def __init__(self, condition, msg):
- self.condition = condition
- self.message = msg
-
- def __call__(self, func):
- def _skipper(*args, **kw):
- """Wrapped skipper function."""
- if not self.condition:
- raise nose.SkipTest(self.message)
- func(*args, **kw)
- _skipper.__name__ = func.__name__
- _skipper.__doc__ = func.__doc__
- return _skipper
+from testtools import TestCase
class skip_unless_attr(object):
@@ -66,7 +32,7 @@
"""Wrapped skipper function."""
testobj = args[0]
if not getattr(testobj, self.attr, False):
- raise nose.SkipTest(self.message)
+ raise TestCase.skipException(self.message)
func(*args, **kw)
_skipper.__name__ = func.__name__
_skipper.__doc__ = func.__doc__
diff --git a/tempest/tests/volume/admin/base.py b/tempest/tests/volume/admin/base.py
index 364be54..21425be 100644
--- a/tempest/tests/volume/admin/base.py
+++ b/tempest/tests/volume/admin/base.py
@@ -15,8 +15,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import nose
-
from tempest import config
import tempest.services.volume.json.admin.volume_types_client \
@@ -40,7 +38,7 @@
if not cls.adm_user and cls.adm_pass and cls.adm_tenant:
msg = ("Missing Volume Admin API credentials "
"in configuration.")
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
@classmethod
def tearDownClass(cls):
diff --git a/tempest/tests/volume/admin/test_volume_types_extra_specs_negative.py b/tempest/tests/volume/admin/test_volume_types_extra_specs_negative.py
index d139425..e7fe701 100644
--- a/tempest/tests/volume/admin/test_volume_types_extra_specs_negative.py
+++ b/tempest/tests/volume/admin/test_volume_types_extra_specs_negative.py
@@ -15,7 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import unittest
+import testtools
import uuid
from nose.plugins.attrib import attr
@@ -42,7 +42,7 @@
def tearDownClass(cls):
cls.client.delete_volume_type(cls.volume_type['id'])
- @unittest.skip('Until bug 1090320 is fixed')
+ @testtools.skip('Until bug 1090320 is fixed')
@raises(exceptions.BadRequest)
@attr(type='negative')
def test_update_no_body(self):
@@ -88,7 +88,7 @@
self.client.create_volume_type_extra_specs(str(uuid.uuid4()),
extra_specs)
- @unittest.skip('Until bug 1090322 is fixed')
+ @testtools.skip('Until bug 1090322 is fixed')
@raises(exceptions.BadRequest)
@attr(type='negative')
def test_create_none_body(self):
@@ -96,7 +96,7 @@
self.client.create_volume_type_extra_specs(self.volume_type['id'],
None)
- @unittest.skip('Until bug 1090322 is fixed')
+ @testtools.skip('Until bug 1090322 is fixed')
@raises(exceptions.BadRequest)
@attr(type='negative')
def test_create_invalid_body(self):
diff --git a/tempest/tests/volume/admin/test_volume_types_negative.py b/tempest/tests/volume/admin/test_volume_types_negative.py
index c2daef9..f53e33c 100644
--- a/tempest/tests/volume/admin/test_volume_types_negative.py
+++ b/tempest/tests/volume/admin/test_volume_types_negative.py
@@ -15,7 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import unittest
+import testtools
import uuid
from nose.plugins.attrib import attr
@@ -40,7 +40,7 @@
display_name=str(uuid.uuid4()),
volume_type=str(uuid.uuid4()))
- @unittest.skip('Until bug 1090356 is fixed')
+ @testtools.skip('Until bug 1090356 is fixed')
@raises(exceptions.BadRequest)
@attr(type='negative')
def test_create_with_empty_name(self):
diff --git a/tempest/tests/volume/base.py b/tempest/tests/volume/base.py
index 33bae45..de78c99 100644
--- a/tempest/tests/volume/base.py
+++ b/tempest/tests/volume/base.py
@@ -19,7 +19,7 @@
import time
import nose
-import unittest2 as unittest
+import testtools
from tempest import clients
from tempest.common.utils.data_utils import rand_name
@@ -29,7 +29,7 @@
LOG = logging.getLogger(__name__)
-class BaseVolumeTest(unittest.TestCase):
+class BaseVolumeTest(testtools.TestCase):
"""Base test case class for all Cinder API tests."""
@@ -66,7 +66,7 @@
cls.os.tenant_name)
except exceptions.EndpointNotFound:
cls.clear_isolated_creds()
- raise nose.SkipTest(skip_msg)
+ raise cls.skipException(skip_msg)
@classmethod
def _get_identity_admin_client(cls):
diff --git a/tempest/tests/volume/test_volumes_list.py b/tempest/tests/volume/test_volumes_list.py
index 2fc1353..92d3d3f 100644
--- a/tempest/tests/volume/test_volumes_list.py
+++ b/tempest/tests/volume/test_volumes_list.py
@@ -94,7 +94,7 @@
"test. This typically means that the backing file "
"size of the nova-volumes group is too small to "
"create the 3 volumes needed by this test case")
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
raise
@classmethod
@@ -141,7 +141,7 @@
"test. This typically means that the backing file "
"size of the nova-volumes group is too small to "
"create the 3 volumes needed by this test case")
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
raise
@classmethod
diff --git a/tempest/whitebox.py b/tempest/whitebox.py
index d78b9e0..03ad63b 100644
--- a/tempest/whitebox.py
+++ b/tempest/whitebox.py
@@ -21,7 +21,6 @@
import subprocess
import sys
-import nose
from sqlalchemy import create_engine, MetaData
from tempest.common.ssh import Client
@@ -59,7 +58,7 @@
def setUpClass(cls):
if not compute.WHITEBOX_ENABLED:
msg = "Whitebox testing disabled"
- raise nose.SkipTest(msg)
+ raise cls.skipException(msg)
super(ComputeWhiteboxTest, cls).setUpClass()
diff --git a/tools/pip-requires b/tools/pip-requires
index fcf1690..dcc859f 100644
--- a/tools/pip-requires
+++ b/tools/pip-requires
@@ -1,7 +1,7 @@
anyjson
nose
httplib2>=0.7.0
-unittest2
+testtools
lxml
boto>=2.2.1
paramiko