Merge "Simplify whitebox/manager"
diff --git a/tempest/manager.py b/tempest/manager.py
index 187e2c6..54a0dec 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -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 @@
                    "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)
diff --git a/tempest/test.py b/tempest/test.py
index 5040f34..7ba63cd 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -27,7 +27,6 @@
 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 @@
         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 @@
                                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
diff --git a/tempest/whitebox/manager.py b/tempest/whitebox/manager.py
index 3bd057c..471d8b4 100644
--- a/tempest/whitebox/manager.py
+++ b/tempest/whitebox/manager.py
@@ -21,12 +21,11 @@
 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 @@
     pass
 
 
-class ComputeWhiteboxTest(test.ComputeFuzzClientTest, WhiteboxTest):
+class ComputeWhiteboxTest(manager.OfficialClientTest):
 
     """
     Base smoke test case class for OpenStack Compute API (Nova)
@@ -64,15 +63,6 @@
         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 @@
         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
diff --git a/tempest/whitebox/test_images_whitebox.py b/tempest/whitebox/test_images_whitebox.py
index dc68336..0afb17e 100644
--- a/tempest/whitebox/test_images_whitebox.py
+++ b/tempest/whitebox/test_images_whitebox.py
@@ -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 @@
     @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 @@
     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