root / kamaki / cli / argument / test.py @ 34c480f2
History | View | Annotate | Download (8.1 kB)
1 |
# Copyright 2013 GRNET S.A. All rights reserved.
|
---|---|
2 |
#
|
3 |
# Redistribution and use in source and binary forms, with or
|
4 |
# without modification, are permitted provided that the following
|
5 |
# conditions are met:
|
6 |
#
|
7 |
# 1. Redistributions of source code must retain the above
|
8 |
# copyright notice, this list of conditions and the following
|
9 |
# disclaimer.
|
10 |
#
|
11 |
# 2. Redistributions in binary form must reproduce the above
|
12 |
# copyright notice, this list of conditions and the following
|
13 |
# disclaimer in the documentation and/or other materials
|
14 |
# provided with the distribution.
|
15 |
#
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 |
# POSSIBILITY OF SUCH DAMAGE.
|
28 |
#
|
29 |
# The views and conclusions contained in the software and
|
30 |
# documentation are those of the authors and should not be
|
31 |
# interpreted as representing official policies, either expressed
|
32 |
# or implied, of GRNET S.A.
|
33 |
|
34 |
from mock import patch, call |
35 |
from unittest import TestCase |
36 |
from StringIO import StringIO |
37 |
from itertools import product |
38 |
|
39 |
from kamaki.cli import argument |
40 |
from kamaki.cli.config import Config |
41 |
|
42 |
|
43 |
cnf_path = 'kamaki.cli.config.Config'
|
44 |
|
45 |
|
46 |
class Argument(TestCase): |
47 |
|
48 |
def test___init__(self): |
49 |
self.assertRaises(ValueError, argument.Argument, 'non-integer') |
50 |
self.assertRaises(AssertionError, argument.Argument, 1) |
51 |
self.assertRaises(AssertionError, argument.Argument, 0, 'noname') |
52 |
self.assertRaises(AssertionError, argument.Argument, 0, '--no name') |
53 |
self.assertRaises(AssertionError, argument.Argument, 0, ['-n', 'n m']) |
54 |
for arity, help, parsed_name, default in ( |
55 |
(0, 'help 0', '--zero', None), |
56 |
(1, 'help 1', ['--one', '-o'], 'lala'), |
57 |
(-1, 'help -1', ['--help', '--or', '--more'], 0), |
58 |
(0, 'help 0 again', ['--again', ], True)): |
59 |
a = argument.Argument(arity, help, parsed_name, default) |
60 |
if arity:
|
61 |
self.assertEqual(arity, a.arity)
|
62 |
self.assertEqual(help, a.help)
|
63 |
|
64 |
exp_name = parsed_name if (
|
65 |
isinstance(parsed_name, list)) else [parsed_name, ] |
66 |
self.assertEqual(exp_name, a.parsed_name)
|
67 |
|
68 |
exp_default = default or (None if arity else False) |
69 |
self.assertEqual(exp_default, a.default)
|
70 |
|
71 |
def test_value(self): |
72 |
a = argument.Argument(1, parsed_name='--value') |
73 |
for value in (None, '', 0, 0.1, -12, [1, 'a', 2.8], (3, 'lala'), 'pi'): |
74 |
a.value = value |
75 |
self.assertEqual(value, a.value)
|
76 |
|
77 |
def test_update_parser(self): |
78 |
for i, arity in enumerate((-1, 0, 1)): |
79 |
arp = argument.ArgumentParser() |
80 |
pname, aname = '--pname%s' % i, 'a_name_%s' % i |
81 |
a = argument.Argument(arity, 'args', pname, 42) |
82 |
a.update_parser(arp, aname) |
83 |
|
84 |
f = StringIO() |
85 |
arp.print_usage(file=f), f.seek(0)
|
86 |
usage, exp = f.readline(), '[%s%s]\n' % (
|
87 |
pname, (' %s' % aname.upper()) if arity else '') |
88 |
self.assertEqual(usage[-len(exp):], exp) |
89 |
del arp
|
90 |
|
91 |
|
92 |
class ConfigArgument(TestCase): |
93 |
|
94 |
def setUp(self): |
95 |
argument._config_arg = argument.ConfigArgument('Recovered Path')
|
96 |
|
97 |
def test_value(self): |
98 |
c = argument._config_arg |
99 |
self.assertEqual(c.value, None) |
100 |
exp = '/some/random/path'
|
101 |
c.value = exp |
102 |
self.assertTrue(isinstance(c.value, Config)) |
103 |
self.assertEqual(c.file_path, exp)
|
104 |
self.assertEqual(c.value.path, exp)
|
105 |
|
106 |
def test_get(self): |
107 |
c = argument._config_arg |
108 |
c.value = None
|
109 |
with patch('%s.get' % cnf_path, return_value='config') as get: |
110 |
self.assertEqual(c.value.get('global', 'config_cli'), 'config') |
111 |
self.assertEqual(get.mock_calls[-1], call('global', 'config_cli')) |
112 |
|
113 |
@patch('%s.keys' % cnf_path, return_value=( |
114 |
'image_cli', 'config_cli', 'history_cli', 'file')) |
115 |
def test_groups(self, keys): |
116 |
c = argument._config_arg |
117 |
c.value = None
|
118 |
cset = set(c.groups)
|
119 |
self.assertTrue(cset.issuperset(['image', 'config', 'history'])) |
120 |
self.assertEqual(keys.mock_calls[-1], call('global')) |
121 |
self.assertFalse('file' in cset) |
122 |
self.assertEqual(keys.mock_calls[-1], call('global')) |
123 |
|
124 |
@patch('%s.items' % cnf_path, return_value=( |
125 |
('image_cli', 'image'), ('file', 'pithos'), |
126 |
('config_cli', 'config'), ('history_cli', 'history'))) |
127 |
def test_cli_specs(self, items): |
128 |
c = argument._config_arg |
129 |
c.value = None
|
130 |
cset = set(c.cli_specs)
|
131 |
self.assertTrue(cset.issuperset([
|
132 |
('image', 'image'), ('config', 'config'), ('history', 'history')])) |
133 |
self.assertEqual(items.mock_calls[-1], call('global')) |
134 |
self.assertFalse(cset.issuperset([('file', 'pithos'), ])) |
135 |
self.assertEqual(items.mock_calls[-1], call('global')) |
136 |
|
137 |
def test_get_global(self): |
138 |
c = argument._config_arg |
139 |
c.value = None
|
140 |
for k, v in ( |
141 |
('config_cli', 'config'), |
142 |
('image_cli', 'image'), |
143 |
('history_cli', 'history')): |
144 |
with patch('%s.get_global' % cnf_path, return_value=v) as gg: |
145 |
self.assertEqual(c.get_global(k), v)
|
146 |
self.assertEqual(gg.mock_calls[-1], call(k)) |
147 |
|
148 |
def test_get_cloud(self): |
149 |
c = argument._config_arg |
150 |
c.value = None
|
151 |
with patch(
|
152 |
'%s.get_cloud' % cnf_path,
|
153 |
return_value='http://cloud') as get_cloud: |
154 |
self.assertTrue(len(c.get_cloud('mycloud', 'url')) > 0) |
155 |
self.assertEqual(get_cloud.mock_calls[-1], call('mycloud', 'url')) |
156 |
with patch(
|
157 |
'%s.get_cloud' % cnf_path,
|
158 |
side_effect=KeyError('no token')) as get_cloud: |
159 |
self.assertRaises(KeyError, c.get_cloud, 'mycloud', 'token') |
160 |
invalidcloud = 'PLEASE_DO_NOT_EVER_NAME_YOUR_CLOUD_LIKE_THIS111'
|
161 |
self.assertRaises(KeyError, c.get_cloud, invalidcloud, 'url') |
162 |
|
163 |
|
164 |
class RuntimeConfigArgument(TestCase): |
165 |
|
166 |
def setUp(self): |
167 |
argument._config_arg = argument.ConfigArgument('Recovered Path')
|
168 |
|
169 |
@patch('kamaki.cli.argument.Argument.__init__') |
170 |
def test___init__(self, arg): |
171 |
config, help, pname, default = 'config', 'help', 'pname', 'default' |
172 |
rca = argument.RuntimeConfigArgument(config, help, pname, default) |
173 |
self.assertTrue(isinstance(rca, argument.RuntimeConfigArgument)) |
174 |
self.assertEqual(rca._config_arg, config)
|
175 |
self.assertEqual(arg.mock_calls[-1], call(1, help, pname, default)) |
176 |
|
177 |
@patch('%s.override' % cnf_path) |
178 |
def test_value(self, override): |
179 |
config, help, pname, default = argument._config_arg, 'help', '-n', 'df' |
180 |
config.value = None
|
181 |
rca = argument.RuntimeConfigArgument(config, help, pname, default) |
182 |
self.assertEqual(rca.value, default)
|
183 |
|
184 |
for options in ('grp', 'grp.opt', 'k v', '=nokey', 2.8, None, 42, ''): |
185 |
self.assertRaises(TypeError, rca.value, options) |
186 |
|
187 |
for options in ('key=val', 'grp.key=val', 'dotted.opt.key=val'): |
188 |
rca.value = options |
189 |
option, sep, val = options.partition('=')
|
190 |
grp, sep, key = option.partition('.')
|
191 |
grp, key = (grp, key) if key else ('global', grp) |
192 |
self.assertEqual(override.mock_calls[-1], call(grp, key, val)) |
193 |
|
194 |
if __name__ == '__main__': |
195 |
from sys import argv |
196 |
from kamaki.cli.test import runTestCase |
197 |
runTestCase(Argument, 'Argument', argv[1:]) |
198 |
runTestCase(ConfigArgument, 'ConfigArgument', argv[1:]) |
199 |
runTestCase(RuntimeConfigArgument, 'RuntimeConfigArgument', argv[1:]) |