Prepare base test class for CLI tests

Change-Id: Iae4a9c88d0e398d295900d58ae014798267fde1e
diff --git a/cli/__init__.py b/cli/__init__.py
index cea0b62..e97fe3e 100644
--- a/cli/__init__.py
+++ b/cli/__init__.py
@@ -16,8 +16,11 @@
 #    under the License.
 
 import logging
+import shlex
+import subprocess
 
 from tempest.openstack.common import cfg
+import tempest.test
 
 LOG = logging.getLogger(__name__)
 
@@ -34,3 +37,45 @@
 cli_group = cfg.OptGroup(name='cli', title="cli Configuration Options")
 CONF.register_group(cli_group)
 CONF.register_opts(cli_opts, group=cli_group)
+
+
+class ClientTestBase(tempest.test.BaseTestCase):
+    @classmethod
+    def setUpClass(cls):
+        if not CONF.cli.enabled:
+            msg = "cli testing disabled"
+            raise cls.skipException(msg)
+        cls.identity = cls.config.identity
+        super(ClientTestBase, cls).setUpClass()
+
+    def __init__(self, *args, **kwargs):
+        super(ClientTestBase, self).__init__(*args, **kwargs)
+
+    def nova(self, action, flags='', params='', admin=True, fail_ok=False):
+        """Executes nova command for the given action."""
+        return self.cmd_with_auth(
+            'nova', action, flags, params, admin, fail_ok)
+
+    def cmd_with_auth(self, cmd, action, flags='', params='',
+                      admin=True, fail_ok=False):
+        """Executes given command with auth attributes appended."""
+        #TODO(jogo) make admin=False work
+        creds = ('--os-username %s --os-tenant-name %s --os-password %s '
+                 '--os-auth-url %s ' % (self.identity.admin_username,
+                 self.identity.admin_tenant_name, self.identity.admin_password,
+                 self.identity.uri))
+        flags = creds + ' ' + flags
+        return self.cmd(cmd, action, flags, params, fail_ok)
+
+    def cmd(self, cmd, action, flags='', params='', fail_ok=False):
+        """Executes specified command for the given action."""
+        cmd = ' '.join([CONF.cli.cli_dir + cmd,
+                        flags, action, params])
+        LOG.info("running: '%s'" % cmd)
+        cmd = shlex.split(cmd)
+        try:
+            result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+        except subprocess.CalledProcessError, e:
+            LOG.error("command output:\n%s" % e.output)
+            raise
+        return result
diff --git a/cli/simple_read_only/test_compute.py b/cli/simple_read_only/test_compute.py
index 073fde1..849ed6f 100644
--- a/cli/simple_read_only/test_compute.py
+++ b/cli/simple_read_only/test_compute.py
@@ -16,14 +16,12 @@
 #    under the License.
 
 import logging
-import shlex
 import subprocess
 
 import testtools
 
 import cli
 
-from tempest import config
 from tempest.openstack.common import cfg
 
 
@@ -33,7 +31,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class SimpleReadOnlyNovaCLientTest(testtools.TestCase):
+class SimpleReadOnlyNovaClientTest(cli.ClientTestBase):
 
     """
     This is a first pass at a simple read only python-novaclient test. This
@@ -47,33 +45,6 @@
 
     """
 
-    @classmethod
-    def setUpClass(cls):
-        if not CONF.cli.enabled:
-            msg = "cli testing disabled"
-            raise cls.skipException(msg)
-        cls.identity = config.TempestConfig().identity
-        super(SimpleReadOnlyNovaCLientTest, cls).setUpClass()
-
-    #NOTE(jogo): This should eventually be moved into a base class
-    def nova(self, action, flags='', params='', admin=True, fail_ok=False):
-        """Executes nova command for the given action."""
-        #TODO(jogo) make admin=False work
-        creds = ('--os-username %s --os-tenant-name %s --os-password %s '
-                 '--os-auth-url %s ' % (self.identity.admin_username,
-                 self.identity.admin_tenant_name, self.identity.admin_password,
-                 self.identity.uri))
-        flags = creds + ' ' + flags
-        cmd = ' '.join([CONF.cli.cli_dir + 'nova', flags, action, params])
-        LOG.info("running: '%s'" % cmd)
-        cmd = shlex.split(cmd)
-        try:
-            result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
-        except subprocess.CalledProcessError, e:
-            LOG.error("command output:\n%s" % e.output)
-            raise
-        return result
-
     def test_admin_fake_action(self):
         self.assertRaises(subprocess.CalledProcessError,
                           self.nova,
diff --git a/tempest/test.py b/tempest/test.py
index 90793ac..e0639b6 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -58,12 +58,11 @@
 
 
 class TestCase(BaseTestCase):
-
-    """
-    Base test case class for all Tempest tests
+    """Base test case class for all Tempest tests
 
     Contains basic setup and convenience methods
     """
+
     manager_class = None
 
     @classmethod