Simplify whitebox/manager

* Allow the generic resource deletion (thing.delete) to
operate on resources allocated in the setUpClass-es too.

* test_images_whitebox.py is using the python
  client libraries as the scenario tests.

* Remove the not used part of the tempest/manager.py

Change-Id: I980a70d22dc7a3a65a26a8197c7888b125eb3b05
This commit is contained in:
Attila Fazekas 2013-07-02 16:15:01 +02:00
parent 7f9a3125bb
commit d6d8629107
4 changed files with 40 additions and 201 deletions

View File

@ -15,41 +15,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from tempest.common import log as logging
import tempest.config
from tempest import exceptions
# Tempest REST Fuzz testing client libs
from tempest.services.compute.json import extensions_client
from tempest.services.compute.json import flavors_client
from tempest.services.compute.json import floating_ips_client
from tempest.services.compute.json import hypervisor_client
from tempest.services.compute.json import images_client
from tempest.services.compute.json import keypairs_client
from tempest.services.compute.json import limits_client
from tempest.services.compute.json import quotas_client
from tempest.services.compute.json import security_groups_client
from tempest.services.compute.json import servers_client
from tempest.services.compute.json import volumes_extensions_client
from tempest.services.network.json import network_client
from tempest.services.volume.json import snapshots_client
from tempest.services.volume.json import volumes_client
NetworkClient = network_client.NetworkClient
ImagesClient = images_client.ImagesClientJSON
FlavorsClient = flavors_client.FlavorsClientJSON
ServersClient = servers_client.ServersClientJSON
LimitsClient = limits_client.LimitsClientJSON
ExtensionsClient = extensions_client.ExtensionsClientJSON
FloatingIPsClient = floating_ips_client.FloatingIPsClientJSON
SecurityGroupsClient = security_groups_client.SecurityGroupsClientJSON
KeyPairsClient = keypairs_client.KeyPairsClientJSON
VolumesExtensionsClient = volumes_extensions_client.VolumesExtensionsClientJSON
VolumesClient = volumes_client.VolumesClientJSON
SnapshotsClient = snapshots_client.SnapshotsClientJSON
QuotasClient = quotas_client.QuotasClientJSON
HypervisorClient = hypervisor_client.HypervisorClientJSON
LOG = logging.getLogger(__name__)
class Manager(object):
@ -73,97 +40,3 @@ class Manager(object):
"tenant_name: %(t)s" %
{'u': username, 'p': password, 't': tenant_name})
raise exceptions.InvalidConfiguration(msg)
class FuzzClientManager(Manager):
"""
Manager class that indicates the client provided by the manager
is a fuzz-testing client that Tempest contains. These fuzz-testing
clients are used to be able to throw random or invalid data at
an endpoint and check for appropriate error messages returned
from the endpoint.
"""
pass
class ComputeFuzzClientManager(FuzzClientManager):
"""
Manager that uses the Tempest REST client that can send
random or invalid data at the OpenStack Compute API
"""
def __init__(self, username=None, password=None, tenant_name=None):
"""
We allow overriding of the credentials used within the various
client classes managed by the Manager object. Left as None, the
standard username/password/tenant_name is used.
:param username: Override of the username
:param password: Override of the password
:param tenant_name: Override of the tenant name
"""
super(ComputeFuzzClientManager, self).__init__()
# If no creds are provided, we fall back on the defaults
# in the config file for the Compute API.
username = username or self.config.identity.username
password = password or self.config.identity.password
tenant_name = tenant_name or self.config.identity.tenant_name
self._validate_credentials(username, password, tenant_name)
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'
client_args = (self.config, username, password, auth_url,
tenant_name)
self.servers_client = ServersClient(*client_args)
self.flavors_client = FlavorsClient(*client_args)
self.images_client = ImagesClient(*client_args)
self.limits_client = LimitsClient(*client_args)
self.extensions_client = ExtensionsClient(*client_args)
self.keypairs_client = KeyPairsClient(*client_args)
self.security_groups_client = SecurityGroupsClient(*client_args)
self.floating_ips_client = FloatingIPsClient(*client_args)
self.volumes_extensions_client = VolumesExtensionsClient(*client_args)
self.volumes_client = VolumesClient(*client_args)
self.snapshots_client = SnapshotsClient(*client_args)
self.quotas_client = QuotasClient(*client_args)
self.network_client = NetworkClient(*client_args)
self.hypervisor_client = HypervisorClient(*client_args)
class ComputeFuzzClientAltManager(Manager):
"""
Manager object that uses the alt_XXX credentials for its
managed client objects
"""
def __init__(self):
conf = tempest.config.TempestConfig()
super(ComputeFuzzClientAltManager, self).__init__(
conf.identity.alt_username,
conf.identity.alt_password,
conf.identity.alt_tenant_name)
class ComputeFuzzClientAdminManager(Manager):
"""
Manager object that uses the alt_XXX credentials for its
managed client objects
"""
def __init__(self):
conf = tempest.config.TempestConfig()
super(ComputeFuzzClientAdminManager, self).__init__(
conf.compute_admin.username,
conf.compute_admin.password,
conf.compute_admin.tenant_name)

View File

@ -27,7 +27,6 @@ from tempest.common import log as logging
from tempest.common.utils.data_utils import rand_name
from tempest import config
from tempest import exceptions
from tempest import manager
LOG = logging.getLogger(__name__)
@ -247,19 +246,22 @@ class TestCase(BaseTestCase):
cls.resource_keys = {}
cls.os_resources = []
def set_resource(self, key, thing):
@classmethod
def set_resource(cls, key, thing):
LOG.debug("Adding %r to shared resources of %s" %
(thing, self.__class__.__name__))
self.resource_keys[key] = thing
self.os_resources.append(thing)
(thing, cls.__name__))
cls.resource_keys[key] = thing
cls.os_resources.append(thing)
def get_resource(self, key):
return self.resource_keys[key]
@classmethod
def get_resource(cls, key):
return cls.resource_keys[key]
def remove_resource(self, key):
thing = self.resource_keys[key]
self.os_resources.remove(thing)
del self.resource_keys[key]
@classmethod
def remove_resource(cls, key):
thing = cls.resource_keys[key]
cls.os_resources.remove(thing)
del cls.resource_keys[key]
def status_timeout(self, things, thing_id, expected_status):
"""
@ -289,13 +291,3 @@ class TestCase(BaseTestCase):
conf.compute.build_interval):
self.fail("Timed out waiting for thing %s to become %s"
% (thing_id, expected_status))
class ComputeFuzzClientTest(TestCase):
"""
Base test case class for OpenStack Compute API (Nova)
that uses the Tempest REST fuzz client libs for calling the API.
"""
manager_class = manager.ComputeFuzzClientManager

View File

@ -21,12 +21,11 @@ import subprocess
import sys
from sqlalchemy import create_engine, MetaData
from tempest.common import log as logging
from tempest.common.ssh import Client
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
from tempest import test
from tempest.scenario import manager
LOG = logging.getLogger(__name__)
@ -47,7 +46,7 @@ class WhiteboxTest(object):
pass
class ComputeWhiteboxTest(test.ComputeFuzzClientTest, WhiteboxTest):
class ComputeWhiteboxTest(manager.OfficialClientTest):
"""
Base smoke test case class for OpenStack Compute API (Nova)
@ -64,15 +63,6 @@ class ComputeWhiteboxTest(test.ComputeFuzzClientTest, WhiteboxTest):
cls.nova_dir = cls.config.whitebox.source_dir
cls.compute_bin_dir = cls.config.whitebox.bin_dir
cls.compute_config_path = cls.config.whitebox.config_path
cls.servers_client = cls.manager.servers_client
cls.images_client = cls.manager.images_client
cls.flavors_client = cls.manager.flavors_client
cls.extensions_client = cls.manager.extensions_client
cls.floating_ips_client = cls.manager.floating_ips_client
cls.keypairs_client = cls.manager.keypairs_client
cls.security_groups_client = cls.manager.security_groups_client
cls.limits_client = cls.manager.limits_client
cls.volumes_client = cls.manager.volumes_client
cls.build_interval = cls.config.compute.build_interval
cls.build_timeout = cls.config.compute.build_timeout
cls.ssh_user = cls.config.compute.ssh_user
@ -80,38 +70,27 @@ class ComputeWhiteboxTest(test.ComputeFuzzClientTest, WhiteboxTest):
cls.image_ref_alt = cls.config.compute.image_ref_alt
cls.flavor_ref = cls.config.compute.flavor_ref
cls.flavor_ref_alt = cls.config.compute.flavor_ref_alt
cls.servers = []
#NOTE(afazekas): Mimics the helper method used in the api tests
@classmethod
def tearDownClass(cls):
# NOTE(jaypipes): Tests often add things in a particular order
# so we destroy resources in the reverse order in which resources
# are added to the test class object
if not cls.os_resources:
return
thing = cls.os_resources.pop()
while True:
LOG.debug("Deleting %r from shared resources of %s" %
(thing, cls.__name__))
# Resources in novaclient all have a delete() method
# which destroys the resource...
thing.delete()
if not cls.os_resources:
return
thing = cls.os_resources.pop()
def create_server(cls, **kwargs):
flavor_ref = cls.config.compute.flavor_ref
image_ref = cls.config.compute.image_ref
name = rand_name(cls.__name__ + "-instance")
if 'name' in kwargs:
name = kwargs.pop('name')
flavor = kwargs.get('flavor', flavor_ref)
image_id = kwargs.get('image_id', image_ref)
@classmethod
def create_server(cls, image_id=None):
"""Wrapper utility that returns a test server."""
server_name = rand_name(cls.__name__ + "-instance")
flavor = cls.flavor_ref
if not image_id:
image_id = cls.image_ref
server = cls.compute_client.servers.create(
name, image_id, flavor, **kwargs)
resp, server = cls.servers_client.create_server(
server_name, image_id, flavor)
cls.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
cls.servers.append(server)
if 'wait_until' in kwargs:
cls.status_timeout(cls.compute_client.servers, server.id,
server['id'], kwargs['wait_until'])
server = cls.compute_client.servers.get(server.id)
cls.set_resource(name, server)
return server
@classmethod

View File

@ -15,23 +15,19 @@
# License for the specific language governing permissions and limitations
# under the License.
from tempest.api.compute import base
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
from tempest.whitebox import manager
#TODO(afazekas): The whitebox tests are using complex testclass/manager
# hierarchy, without a real need. It is difficult to maintain.
# They could share more code with scenario tests.
from novaclient import exceptions
class ImagesWhiteboxTest(manager.ComputeWhiteboxTest, base.BaseComputeTest):
class ImagesWhiteboxTest(manager.ComputeWhiteboxTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
super(ImagesWhiteboxTest, cls).setUpClass()
cls.client = cls.images_client
cls.create_image = cls.compute_client.servers.create_image
cls.connection, cls.meta = cls.get_db_handle_and_meta()
cls.shared_server = cls.create_server()
cls.image_ids = []
@ -39,7 +35,6 @@ class ImagesWhiteboxTest(manager.ComputeWhiteboxTest, base.BaseComputeTest):
@classmethod
def tearDownClass(cls):
"""Delete images and server after a test is executed."""
cls.servers_client.delete_server(cls.shared_server['id'])
for image_id in cls.image_ids:
cls.client.delete_image(image_id)
cls.image_ids.remove(image_id)
@ -62,18 +57,18 @@ class ImagesWhiteboxTest(manager.ComputeWhiteboxTest, base.BaseComputeTest):
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,
self.update_state(self.shared_server.id, vm_state,
task_state, deleted)
image_name = rand_name('snap-')
self.assertRaises(exceptions.Duplicate,
self.client.create_image,
self.shared_server['id'], image_name)
self.assertRaises(exceptions.Conflict,
self.create_image,
self.shared_server.id, image_name)
except Exception:
self.fail("Should not allow create image when vm_state=%s and "
"task_state=%s" % (vm_state, task_state))
finally:
self.update_state(self.shared_server['id'], 'active', None)
self.update_state(self.shared_server.id, 'active', None)
def test_create_image_when_vm_eq_building_task_eq_scheduling(self):
# 409 error when instance states are building,scheduling