# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2013 OpenStack Foundation # 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 logging import shlex import subprocess from oslo.config import cfg import cli.output_parser import tempest.test LOG = logging.getLogger(__name__) cli_opts = [ cfg.BoolOpt('enabled', default=True, help="enable cli tests"), cfg.StrOpt('cli_dir', default='/usr/local/bin/', help="directory where python client binaries are located"), ] CONF = cfg.CONF 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): self.parser = cli.output_parser 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 nova_manage(self, action, flags='', params='', fail_ok=False, merge_stderr=False): """Executes nova-manage command for the given action.""" return self.cmd( 'nova-manage', action, flags, params, fail_ok, merge_stderr) def keystone(self, action, flags='', params='', admin=True, fail_ok=False): """Executes keystone command for the given action.""" return self.cmd_with_auth( 'keystone', action, flags, params, admin, fail_ok) def glance(self, action, flags='', params='', admin=True, fail_ok=False): """Executes glance command for the given action.""" return self.cmd_with_auth( 'glance', 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 check_output(self, cmd, **kwargs): # substitutes subprocess.check_output which is not in python2.6 kwargs['stdout'] = subprocess.PIPE proc = subprocess.Popen(cmd, **kwargs) output = proc.communicate()[0] if proc.returncode != 0: raise CommandFailed(proc.returncode, cmd, output) return output def cmd(self, cmd, action, flags='', params='', fail_ok=False, merge_stderr=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: if merge_stderr: result = self.check_output(cmd, stderr=subprocess.STDOUT) else: with open('/dev/null', 'w') as devnull: result = self.check_output(cmd, stderr=devnull) except subprocess.CalledProcessError, e: LOG.error("command output:\n%s" % e.output) raise return result def assertTableStruct(self, items, field_names): """Verify that all items has keys listed in field_names.""" for item in items: for field in field_names: self.assertIn(field, item) class CommandFailed(subprocess.CalledProcessError): # adds output attribute for python2.6 def __init__(self, returncode, cmd, output): super(CommandFailed, self).__init__(returncode, cmd) self.output = output