blob: a3038d236ac66c0a3dd49ac8f66a16fac8a1d465 [file] [log] [blame]
Joe Gordonc97f5c72013-02-14 01:15:57 +00001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2013 OpenStack Foundation
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
18import logging
Pavel Sedláka2b757c2013-02-25 18:16:04 +010019import shlex
20import subprocess
Joe Gordonc97f5c72013-02-14 01:15:57 +000021
Matthew Treinish90aedd12013-02-25 17:56:49 -050022from oslo.config import cfg
23
Pavel Sedlák5ce5c032013-02-25 18:41:30 +010024import cli.output_parser
Pavel Sedláka2b757c2013-02-25 18:16:04 +010025import tempest.test
Joe Gordonc97f5c72013-02-14 01:15:57 +000026
Matthew Treinish90aedd12013-02-25 17:56:49 -050027
Joe Gordonc97f5c72013-02-14 01:15:57 +000028LOG = logging.getLogger(__name__)
29
30cli_opts = [
31 cfg.BoolOpt('enabled',
32 default=True,
33 help="enable cli tests"),
34 cfg.StrOpt('cli_dir',
35 default='/usr/local/bin/',
36 help="directory where python client binaries are located"),
37]
38
39CONF = cfg.CONF
40cli_group = cfg.OptGroup(name='cli', title="cli Configuration Options")
41CONF.register_group(cli_group)
42CONF.register_opts(cli_opts, group=cli_group)
Pavel Sedláka2b757c2013-02-25 18:16:04 +010043
44
45class ClientTestBase(tempest.test.BaseTestCase):
46 @classmethod
47 def setUpClass(cls):
48 if not CONF.cli.enabled:
49 msg = "cli testing disabled"
50 raise cls.skipException(msg)
51 cls.identity = cls.config.identity
52 super(ClientTestBase, cls).setUpClass()
53
54 def __init__(self, *args, **kwargs):
Pavel Sedlák5ce5c032013-02-25 18:41:30 +010055 self.parser = cli.output_parser
Pavel Sedláka2b757c2013-02-25 18:16:04 +010056 super(ClientTestBase, self).__init__(*args, **kwargs)
57
58 def nova(self, action, flags='', params='', admin=True, fail_ok=False):
59 """Executes nova command for the given action."""
60 return self.cmd_with_auth(
61 'nova', action, flags, params, admin, fail_ok)
62
Joe Gordone8b0e152013-03-25 13:37:15 -040063 def nova_manage(self, action, flags='', params='', fail_ok=False,
Joe Gordon0e7cbf82013-03-25 19:49:12 +000064 merge_stderr=False):
Joe Gordon4edb6452013-03-05 21:18:59 +000065 """Executes nova-manage command for the given action."""
66 return self.cmd(
Joe Gordone8b0e152013-03-25 13:37:15 -040067 'nova-manage', action, flags, params, fail_ok, merge_stderr)
Joe Gordon4edb6452013-03-05 21:18:59 +000068
Pavel Sedlák5ce5c032013-02-25 18:41:30 +010069 def keystone(self, action, flags='', params='', admin=True, fail_ok=False):
70 """Executes keystone command for the given action."""
71 return self.cmd_with_auth(
72 'keystone', action, flags, params, admin, fail_ok)
73
afazekasf35f9402013-03-25 14:51:13 +010074 def glance(self, action, flags='', params='', admin=True, fail_ok=False):
75 """Executes glance command for the given action."""
76 return self.cmd_with_auth(
77 'glance', action, flags, params, admin, fail_ok)
78
Pavel Sedláka2b757c2013-02-25 18:16:04 +010079 def cmd_with_auth(self, cmd, action, flags='', params='',
80 admin=True, fail_ok=False):
81 """Executes given command with auth attributes appended."""
82 #TODO(jogo) make admin=False work
83 creds = ('--os-username %s --os-tenant-name %s --os-password %s '
84 '--os-auth-url %s ' % (self.identity.admin_username,
85 self.identity.admin_tenant_name, self.identity.admin_password,
86 self.identity.uri))
87 flags = creds + ' ' + flags
88 return self.cmd(cmd, action, flags, params, fail_ok)
89
Pavel Sedlák1053bd32013-04-16 16:47:40 +020090 def check_output(self, cmd, **kwargs):
91 # substitutes subprocess.check_output which is not in python2.6
92 kwargs['stdout'] = subprocess.PIPE
93 proc = subprocess.Popen(cmd, **kwargs)
94 output = proc.communicate()[0]
95 if proc.returncode != 0:
96 raise CommandFailed(proc.returncode, cmd, output)
97 return output
98
Joe Gordone8b0e152013-03-25 13:37:15 -040099 def cmd(self, cmd, action, flags='', params='', fail_ok=False,
Joe Gordon0e7cbf82013-03-25 19:49:12 +0000100 merge_stderr=False):
Pavel Sedláka2b757c2013-02-25 18:16:04 +0100101 """Executes specified command for the given action."""
102 cmd = ' '.join([CONF.cli.cli_dir + cmd,
103 flags, action, params])
104 LOG.info("running: '%s'" % cmd)
105 cmd = shlex.split(cmd)
106 try:
Joe Gordone8b0e152013-03-25 13:37:15 -0400107 if merge_stderr:
Pavel Sedlák1053bd32013-04-16 16:47:40 +0200108 result = self.check_output(cmd, stderr=subprocess.STDOUT)
Joe Gordone8b0e152013-03-25 13:37:15 -0400109 else:
Pavel Sedlák1053bd32013-04-16 16:47:40 +0200110 with open('/dev/null', 'w') as devnull:
111 result = self.check_output(cmd, stderr=devnull)
Pavel Sedláka2b757c2013-02-25 18:16:04 +0100112 except subprocess.CalledProcessError, e:
113 LOG.error("command output:\n%s" % e.output)
114 raise
115 return result
Pavel Sedlák5ce5c032013-02-25 18:41:30 +0100116
117 def assertTableStruct(self, items, field_names):
118 """Verify that all items has keys listed in field_names."""
119 for item in items:
120 for field in field_names:
121 self.assertIn(field, item)
Pavel Sedlák1053bd32013-04-16 16:47:40 +0200122
123
124class CommandFailed(subprocess.CalledProcessError):
125 # adds output attribute for python2.6
126 def __init__(self, returncode, cmd, output):
127 super(CommandFailed, self).__init__(returncode, cmd)
128 self.output = output