Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / config / test.py @ 534e7bbb

History | View | Annotate | Download (19.9 kB)

1 9f5cbafe Stavros Sachtouris
# Copyright 2013 GRNET S.A. All rights reserved.
2 9f5cbafe Stavros Sachtouris
#
3 9f5cbafe Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 9f5cbafe Stavros Sachtouris
# without modification, are permitted provided that the following
5 9f5cbafe Stavros Sachtouris
# conditions are met:
6 9f5cbafe Stavros Sachtouris
#
7 9f5cbafe Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 9f5cbafe Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 9f5cbafe Stavros Sachtouris
#      disclaimer.
10 9f5cbafe Stavros Sachtouris
#
11 9f5cbafe Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 9f5cbafe Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 9f5cbafe Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 9f5cbafe Stavros Sachtouris
#      provided with the distribution.
15 9f5cbafe Stavros Sachtouris
#
16 9f5cbafe Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 9f5cbafe Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 9f5cbafe Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 9f5cbafe Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 9f5cbafe Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 9f5cbafe Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 9f5cbafe Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 9f5cbafe Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 9f5cbafe Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 9f5cbafe Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 9f5cbafe Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 9f5cbafe Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 9f5cbafe Stavros Sachtouris
#
29 9f5cbafe Stavros Sachtouris
# The views and conclusions contained in the software and
30 9f5cbafe Stavros Sachtouris
# documentation are those of the authors and should not be
31 9f5cbafe Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 9f5cbafe Stavros Sachtouris
# or implied, of GRNET S.A.
33 9f5cbafe Stavros Sachtouris
34 f767b407 Stavros Sachtouris
from mock import patch, call
35 9f5cbafe Stavros Sachtouris
from unittest import TestCase
36 f767b407 Stavros Sachtouris
from itertools import product
37 f767b407 Stavros Sachtouris
import os
38 c5997814 Stavros Sachtouris
from tempfile import NamedTemporaryFile
39 c5997814 Stavros Sachtouris
from io import StringIO
40 9f5cbafe Stavros Sachtouris
41 8556d269 Stavros Sachtouris
from kamaki.cli.config import HEADER
42 8556d269 Stavros Sachtouris
43 f767b407 Stavros Sachtouris
44 f767b407 Stavros Sachtouris
def _2steps_gen(limit=2):
45 f767b407 Stavros Sachtouris
    counter, ret = 0, None
46 f767b407 Stavros Sachtouris
    while True:
47 f767b407 Stavros Sachtouris
        if counter >= limit:
48 f767b407 Stavros Sachtouris
            ret = None if ret else 'something'
49 f767b407 Stavros Sachtouris
            counter = 0
50 f767b407 Stavros Sachtouris
        counter += 1
51 f767b407 Stavros Sachtouris
        yield ret
52 f767b407 Stavros Sachtouris
53 f767b407 Stavros Sachtouris
_2value_gen = _2steps_gen()
54 f767b407 Stavros Sachtouris
55 f767b407 Stavros Sachtouris
56 f767b407 Stavros Sachtouris
class Config(TestCase):
57 f767b407 Stavros Sachtouris
    """Test Config methods"""
58 f767b407 Stavros Sachtouris
59 3564be49 Stavros Sachtouris
    def setUp(self):
60 3564be49 Stavros Sachtouris
        self.f = NamedTemporaryFile()
61 3564be49 Stavros Sachtouris
62 8556d269 Stavros Sachtouris
        from kamaki.cli.config import DEFAULTS
63 8556d269 Stavros Sachtouris
64 8556d269 Stavros Sachtouris
        self.DEFAULTS = dict()
65 8556d269 Stavros Sachtouris
        for k, v in DEFAULTS.items():
66 8556d269 Stavros Sachtouris
            self.DEFAULTS[k] = dict(v) if isinstance(v, dict) else v
67 8556d269 Stavros Sachtouris
68 8556d269 Stavros Sachtouris
        self.config_file_content = [
69 8556d269 Stavros Sachtouris
            HEADER,
70 8556d269 Stavros Sachtouris
            '[global]\n',
71 8556d269 Stavros Sachtouris
            'max_threads = 5\n',
72 8556d269 Stavros Sachtouris
            'default_cloud = ~mycloud\n',
73 8556d269 Stavros Sachtouris
            'file_cli = pithos\n',
74 8556d269 Stavros Sachtouris
            'history_file = /home/user/.kamaki.history\n',
75 8556d269 Stavros Sachtouris
            'colors = off\n',
76 8556d269 Stavros Sachtouris
            'config_cli = config\n',
77 8556d269 Stavros Sachtouris
            'history_cli = history\n',
78 8556d269 Stavros Sachtouris
            'log_token = off\n',
79 8556d269 Stavros Sachtouris
            'server_cli = cyclades\n',
80 8556d269 Stavros Sachtouris
            'user_cli = astakos\n',
81 8556d269 Stavros Sachtouris
            'log_data = off\n',
82 8556d269 Stavros Sachtouris
            'flavor_cli = cyclades\n',
83 8556d269 Stavros Sachtouris
            'image_cli = image\n',
84 8556d269 Stavros Sachtouris
            'log_file = /home/user/.kamaki.log\n',
85 8556d269 Stavros Sachtouris
            'network_cli = cyclades\n',
86 8556d269 Stavros Sachtouris
            'log_pid = off\n',
87 8556d269 Stavros Sachtouris
            '\n',
88 8556d269 Stavros Sachtouris
            '[cloud "demo"]\n',
89 8556d269 Stavros Sachtouris
            'url = https://demo.example.com\n',
90 8556d269 Stavros Sachtouris
            'token = t0k3n-0f-d3m0-3x4mp13\n',
91 8556d269 Stavros Sachtouris
            '\n',
92 8556d269 Stavros Sachtouris
            '[cloud "~mycloud"]\n',
93 8556d269 Stavros Sachtouris
            'url = https://example.com\n',
94 8556d269 Stavros Sachtouris
            'pithos_container = images\n']
95 8556d269 Stavros Sachtouris
96 8556d269 Stavros Sachtouris
    def tearDown(self):
97 3564be49 Stavros Sachtouris
        try:
98 3564be49 Stavros Sachtouris
            self.f.close()
99 3564be49 Stavros Sachtouris
        except Exception:
100 3564be49 Stavros Sachtouris
            pass
101 8556d269 Stavros Sachtouris
        finally:
102 8556d269 Stavros Sachtouris
            from kamaki.cli.config import DEFAULTS
103 8556d269 Stavros Sachtouris
            keys = DEFAULTS.keys()
104 8556d269 Stavros Sachtouris
            for k in keys:
105 8556d269 Stavros Sachtouris
                DEFAULTS.pop(k)
106 8556d269 Stavros Sachtouris
            for k, v in self.DEFAULTS.items():
107 8556d269 Stavros Sachtouris
                DEFAULTS[k] = v
108 3564be49 Stavros Sachtouris
109 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.remove_section')
110 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.items', return_value=(
111 f767b407 Stavros Sachtouris
        ('k1', 'v1'), ('k2', 'v2')))
112 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.sections', return_value=('a', 'b'))
113 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.set_cloud')
114 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.read')
115 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config._load_defaults')
116 f767b407 Stavros Sachtouris
    def test___init__(
117 f767b407 Stavros Sachtouris
            self, _ld, c_read, c_set_cloud, c_sections, c_items,
118 f767b407 Stavros Sachtouris
            c_remove_section):
119 f767b407 Stavros Sachtouris
        from kamaki.cli.config import (
120 f767b407 Stavros Sachtouris
            Config, RawConfigParser, CONFIG_ENV, CONFIG_PATH)
121 f767b407 Stavros Sachtouris
        _ld_num, c_sections_num, c_items_num, c_set_cloud_num = 0, 0, 0, 0
122 f767b407 Stavros Sachtouris
        c_remove_section_num, gen_call = 0, [call('a'), call('b')]
123 f767b407 Stavros Sachtouris
        for path, with_defaults in product((None, '/a/path'), (True, False)):
124 f767b407 Stavros Sachtouris
            with patch(
125 f767b407 Stavros Sachtouris
                    'kamaki.cli.config.Config._cloud_name',
126 f767b407 Stavros Sachtouris
                    return_value=_2value_gen.next()) as _cloud_name:
127 f767b407 Stavros Sachtouris
                cnf = Config(path=path, with_defaults=with_defaults)
128 f767b407 Stavros Sachtouris
                self.assertTrue(isinstance(cnf, RawConfigParser))
129 f767b407 Stavros Sachtouris
                cpath = path or os.environ.get(CONFIG_ENV, CONFIG_PATH)
130 f767b407 Stavros Sachtouris
                self.assertEqual(cnf.path, cpath)
131 f767b407 Stavros Sachtouris
                if with_defaults:
132 f767b407 Stavros Sachtouris
                    _ld_num += 1
133 f767b407 Stavros Sachtouris
                    self.assertEqual(_ld.mock_calls[-1], call())
134 f767b407 Stavros Sachtouris
                self.assertEqual(len(_ld.mock_calls), _ld_num)
135 f767b407 Stavros Sachtouris
                self.assertEqual(c_read.mock_calls[-1], call(cpath))
136 f767b407 Stavros Sachtouris
137 f767b407 Stavros Sachtouris
                c_sections_num += 1
138 f767b407 Stavros Sachtouris
                self.assertEqual(len(c_sections.mock_calls), c_sections_num)
139 f767b407 Stavros Sachtouris
                self.assertEqual(c_sections.mock_calls[-1], call())
140 f767b407 Stavros Sachtouris
141 f767b407 Stavros Sachtouris
                self.assertEqual(_cloud_name.mock_calls, gen_call)
142 f767b407 Stavros Sachtouris
143 f767b407 Stavros Sachtouris
                r = _2value_gen.next()
144 f767b407 Stavros Sachtouris
                if r:
145 f767b407 Stavros Sachtouris
                    c_items_num += 2
146 f767b407 Stavros Sachtouris
                    self.assertEqual(c_items.mock_calls[-2:], gen_call)
147 f767b407 Stavros Sachtouris
                    c_set_cloud_num += 4
148 f767b407 Stavros Sachtouris
                    self.assertEqual(c_set_cloud.mock_calls[-4:], [
149 c5997814 Stavros Sachtouris
                        call(r, 'k1', 'v1'), call(r, 'k2', 'v2')] * 2)
150 f767b407 Stavros Sachtouris
                    c_remove_section_num += 2
151 f767b407 Stavros Sachtouris
                    self.assertEqual(
152 f767b407 Stavros Sachtouris
                        c_remove_section.mock_calls[-2:], gen_call)
153 f767b407 Stavros Sachtouris
                self.assertEqual(len(c_items.mock_calls), c_items_num)
154 f767b407 Stavros Sachtouris
                self.assertEqual(len(c_set_cloud.mock_calls), c_set_cloud_num)
155 f767b407 Stavros Sachtouris
                self.assertEqual(
156 f767b407 Stavros Sachtouris
                    len(c_remove_section.mock_calls), c_remove_section_num)
157 9f5cbafe Stavros Sachtouris
158 c5997814 Stavros Sachtouris
    def test__cloud_name(self):
159 c5997814 Stavros Sachtouris
        from kamaki.cli.config import (
160 c5997814 Stavros Sachtouris
            Config, CLOUD_PREFIX, InvalidCloudNameError)
161 c5997814 Stavros Sachtouris
        cn = Config._cloud_name
162 c5997814 Stavros Sachtouris
        self.assertEqual(cn('non%s name' % CLOUD_PREFIX), None)
163 c5997814 Stavros Sachtouris
        for invalid in ('"!@#$%^&())_"', '"a b c"', u'"\xce\xcd"', 'naked'):
164 c5997814 Stavros Sachtouris
            self.assertRaises(
165 c5997814 Stavros Sachtouris
                InvalidCloudNameError, cn, '%s %s' % (CLOUD_PREFIX, invalid))
166 c5997814 Stavros Sachtouris
        for valid in ('word', '~okeanos', 'd0t.ted', 'ha$h#ed'):
167 c5997814 Stavros Sachtouris
            self.assertEqual(cn('%s "%s"' % (CLOUD_PREFIX, valid)), valid)
168 c5997814 Stavros Sachtouris
169 c5997814 Stavros Sachtouris
    def test_rescue_old_file(self):
170 c5997814 Stavros Sachtouris
        from kamaki.cli.config import Config
171 3564be49 Stavros Sachtouris
172 3564be49 Stavros Sachtouris
        content0 = list(self.config_file_content)
173 c5997814 Stavros Sachtouris
174 c5997814 Stavros Sachtouris
        def make_file(lines):
175 c5997814 Stavros Sachtouris
            f = NamedTemporaryFile()
176 c5997814 Stavros Sachtouris
            f.writelines(lines)
177 c5997814 Stavros Sachtouris
            f.flush()
178 c5997814 Stavros Sachtouris
            return f
179 c5997814 Stavros Sachtouris
180 c5997814 Stavros Sachtouris
        with make_file(content0) as f:
181 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
182 c5997814 Stavros Sachtouris
            self.assertEqual([], _cnf.rescue_old_file())
183 c5997814 Stavros Sachtouris
        del _cnf
184 c5997814 Stavros Sachtouris
185 c5997814 Stavros Sachtouris
        content1, sample = list(content0), 'xyz_cli = XYZ_specs'
186 c5997814 Stavros Sachtouris
        content1.insert(2, '%s\n' % sample)
187 c5997814 Stavros Sachtouris
188 c5997814 Stavros Sachtouris
        with make_file(content1) as f:
189 8556d269 Stavros Sachtouris
            f.seek(0)
190 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
191 8556d269 Stavros Sachtouris
            self.assertEqual(
192 8556d269 Stavros Sachtouris
                sorted(['global.%s' % sample]), sorted(_cnf.rescue_old_file()))
193 c5997814 Stavros Sachtouris
        del _cnf
194 c5997814 Stavros Sachtouris
195 c5997814 Stavros Sachtouris
        content2, sample = list(content0), 'http://www.example2.org'
196 c5997814 Stavros Sachtouris
        content2.insert(2, 'url = %s\n' % sample)
197 c5997814 Stavros Sachtouris
        err = StringIO()
198 c5997814 Stavros Sachtouris
199 c5997814 Stavros Sachtouris
        with make_file(content2) as f:
200 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
201 c5997814 Stavros Sachtouris
            self.assertEqual([], _cnf.rescue_old_file(err=err))
202 c5997814 Stavros Sachtouris
            self.assertEqual(
203 c5997814 Stavros Sachtouris
                '... rescue global.url => cloud.default.url\n', err.getvalue())
204 c5997814 Stavros Sachtouris
            self.assertEqual(sample, _cnf.get_cloud('default', 'url'))
205 c5997814 Stavros Sachtouris
        del _cnf
206 c5997814 Stavros Sachtouris
207 c5997814 Stavros Sachtouris
        content3 = list(content0)
208 c5997814 Stavros Sachtouris
        content3.insert(
209 c5997814 Stavros Sachtouris
            2, 'url = http://example1.com\nurl = http://example2.com\n')
210 c5997814 Stavros Sachtouris
211 c5997814 Stavros Sachtouris
        with make_file(content3) as f:
212 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
213 c5997814 Stavros Sachtouris
            self.assertEqual([], _cnf.rescue_old_file(err=err))
214 c5997814 Stavros Sachtouris
            self.assertEqual(
215 c5997814 Stavros Sachtouris
                2 * '... rescue global.url => cloud.default.url\n',
216 c5997814 Stavros Sachtouris
                err.getvalue())
217 c5997814 Stavros Sachtouris
            self.assertEqual(
218 c5997814 Stavros Sachtouris
                'http://example2.com', _cnf.get_cloud('default', 'url'))
219 c5997814 Stavros Sachtouris
        del _cnf
220 c5997814 Stavros Sachtouris
221 c5997814 Stavros Sachtouris
        content4 = list(content0)
222 c5997814 Stavros Sachtouris
        content4.insert(2, 'url = http://example1.com\n')
223 c5997814 Stavros Sachtouris
        content4.append('\n[cloud "default"]\nurl=http://example2.com\n')
224 c5997814 Stavros Sachtouris
225 c5997814 Stavros Sachtouris
        with make_file(content4) as f:
226 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
227 c5997814 Stavros Sachtouris
            from kamaki.cli.errors import CLISyntaxError
228 c5997814 Stavros Sachtouris
            self.assertRaises(CLISyntaxError, _cnf.rescue_old_file)
229 c5997814 Stavros Sachtouris
        del _cnf
230 c5997814 Stavros Sachtouris
231 c5997814 Stavros Sachtouris
        content5 = list(content0)
232 c5997814 Stavros Sachtouris
        extras = [
233 c5997814 Stavros Sachtouris
            ('pithos_cli', 'pithos'), ('store_cli', 'pithos'),
234 c5997814 Stavros Sachtouris
            ('storage_cli', 'pithos'), ('compute_cli', 'cyclades'),
235 c5997814 Stavros Sachtouris
            ('cyclades_cli', 'cyclades')]
236 c5997814 Stavros Sachtouris
        for sample in extras:
237 c5997814 Stavros Sachtouris
            content5.insert(2, '%s = %s\n' % sample)
238 c5997814 Stavros Sachtouris
239 c5997814 Stavros Sachtouris
        with make_file(content5) as f:
240 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
241 c5997814 Stavros Sachtouris
            self.assertEqual(
242 c5997814 Stavros Sachtouris
                sorted(['global.%s = %s' % sample for sample in extras]),
243 c5997814 Stavros Sachtouris
                 sorted(_cnf.rescue_old_file()))
244 c5997814 Stavros Sachtouris
245 3564be49 Stavros Sachtouris
    def test_guess_version(self):
246 3564be49 Stavros Sachtouris
        from kamaki.cli.config import Config
247 3564be49 Stavros Sachtouris
        from kamaki.cli.logger import add_file_logger
248 3564be49 Stavros Sachtouris
249 3564be49 Stavros Sachtouris
        def make_log_file():
250 3564be49 Stavros Sachtouris
            f = NamedTemporaryFile()
251 3564be49 Stavros Sachtouris
            add_file_logger('kamaki.cli.config', filename=f.name)
252 3564be49 Stavros Sachtouris
            return f
253 3564be49 Stavros Sachtouris
254 3564be49 Stavros Sachtouris
        def make_file(lines):
255 3564be49 Stavros Sachtouris
            f = NamedTemporaryFile()
256 3564be49 Stavros Sachtouris
            f.writelines(lines)
257 3564be49 Stavros Sachtouris
            f.flush()
258 3564be49 Stavros Sachtouris
            return f
259 3564be49 Stavros Sachtouris
260 3564be49 Stavros Sachtouris
        with make_file([]) as f:
261 3564be49 Stavros Sachtouris
            with make_log_file() as logf:
262 3564be49 Stavros Sachtouris
                _cnf = Config(path=f.name)
263 3564be49 Stavros Sachtouris
                self.assertEqual(0.9, _cnf.guess_version())
264 3564be49 Stavros Sachtouris
                exp = 'All heuristics failed, cannot decide\n'
265 3564be49 Stavros Sachtouris
                logf.file.seek(- len(exp), 2)
266 3564be49 Stavros Sachtouris
                self.assertEqual(exp, logf.read())
267 3564be49 Stavros Sachtouris
268 3564be49 Stavros Sachtouris
        content0 = list(self.config_file_content)
269 3564be49 Stavros Sachtouris
270 3564be49 Stavros Sachtouris
        with make_file(content0) as f:
271 3564be49 Stavros Sachtouris
            with make_log_file() as logf:
272 3564be49 Stavros Sachtouris
                _cnf = Config(path=f.name)
273 3564be49 Stavros Sachtouris
                self.assertEqual(0.9, _cnf.guess_version())
274 3564be49 Stavros Sachtouris
                exp = '... found cloud "demo"\n'
275 3564be49 Stavros Sachtouris
                logf.seek(- len(exp), 2)
276 3564be49 Stavros Sachtouris
                self.assertEqual(exp, logf.read())
277 3564be49 Stavros Sachtouris
278 3564be49 Stavros Sachtouris
        for term in ('url', 'token'):
279 3564be49 Stavros Sachtouris
            content1 = list(content0)
280 3564be49 Stavros Sachtouris
            content1.insert(2, '%s = some_value' % term)
281 3564be49 Stavros Sachtouris
282 3564be49 Stavros Sachtouris
            with make_file(content1) as f:
283 3564be49 Stavros Sachtouris
                with make_log_file() as logf:
284 3564be49 Stavros Sachtouris
                    _cnf = Config(path=f.name)
285 3564be49 Stavros Sachtouris
                    self.assertEqual(0.8, _cnf.guess_version())
286 3564be49 Stavros Sachtouris
                    exp = '..... config file has an old global section\n'
287 3564be49 Stavros Sachtouris
                    logf.seek(- len(exp), 2)
288 3564be49 Stavros Sachtouris
                    self.assertEqual(exp, logf.read())
289 3564be49 Stavros Sachtouris
290 3564be49 Stavros Sachtouris
    def test_get_cloud(self):
291 3564be49 Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX
292 3564be49 Stavros Sachtouris
293 3564be49 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
294 3564be49 Stavros Sachtouris
        d = dict(opt1='v1', opt2='v2')
295 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=d) as get:
296 3564be49 Stavros Sachtouris
            self.assertEqual('v1', _cnf.get_cloud('mycloud', 'opt1'))
297 3564be49 Stavros Sachtouris
            self.assertEqual(
298 3564be49 Stavros Sachtouris
                get.mock_calls[-1], call(CLOUD_PREFIX, 'mycloud'))
299 3564be49 Stavros Sachtouris
            self.assertRaises(KeyError, _cnf.get_cloud, 'mycloud', 'opt3')
300 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=0) as get:
301 3564be49 Stavros Sachtouris
            self.assertRaises(KeyError, _cnf.get_cloud, 'mycloud', 'opt1')
302 3564be49 Stavros Sachtouris
303 3564be49 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.set')
304 3564be49 Stavros Sachtouris
    def test_set_cloud(self, c_set):
305 3564be49 Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX
306 3564be49 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
307 3564be49 Stavros Sachtouris
308 3564be49 Stavros Sachtouris
        d = dict(k='v')
309 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=d) as get:
310 3564be49 Stavros Sachtouris
            _cnf.set_cloud('mycloud', 'opt', 'val')
311 3564be49 Stavros Sachtouris
            get.assert_called_once_with(CLOUD_PREFIX, 'mycloud')
312 3564be49 Stavros Sachtouris
            d['opt'] = 'val'
313 3564be49 Stavros Sachtouris
            self.assertEqual(
314 3564be49 Stavros Sachtouris
                c_set.mock_calls[-1], call(CLOUD_PREFIX, 'mycloud', d))
315 3564be49 Stavros Sachtouris
316 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=None) as get:
317 3564be49 Stavros Sachtouris
            _cnf.set_cloud('mycloud', 'opt', 'val')
318 3564be49 Stavros Sachtouris
            get.assert_called_once_with(CLOUD_PREFIX, 'mycloud')
319 3564be49 Stavros Sachtouris
            d = dict(opt='val')
320 3564be49 Stavros Sachtouris
            self.assertEqual(
321 3564be49 Stavros Sachtouris
                c_set.mock_calls[-1], call(CLOUD_PREFIX, 'mycloud', d))
322 3564be49 Stavros Sachtouris
323 3564be49 Stavros Sachtouris
        with patch(
324 3564be49 Stavros Sachtouris
                'kamaki.cli.config.Config.get', side_effect=KeyError()) as get:
325 3564be49 Stavros Sachtouris
            _cnf.set_cloud('mycloud', 'opt', 'val')
326 3564be49 Stavros Sachtouris
            get.assert_called_once_with(CLOUD_PREFIX, 'mycloud')
327 3564be49 Stavros Sachtouris
            d = dict(opt='val')
328 3564be49 Stavros Sachtouris
            self.assertEqual(
329 3564be49 Stavros Sachtouris
                c_set.mock_calls[-1], call(CLOUD_PREFIX, 'mycloud', d))
330 3564be49 Stavros Sachtouris
331 2e616dbd Stavros Sachtouris
    def test__load_defaults(self):
332 2e616dbd Stavros Sachtouris
        from kamaki.cli.config import Config, DEFAULTS
333 2e616dbd Stavros Sachtouris
        _cnf = Config(path=self.f.name)
334 2e616dbd Stavros Sachtouris
335 2e616dbd Stavros Sachtouris
        with patch('kamaki.cli.config.Config.set') as c_set:
336 2e616dbd Stavros Sachtouris
            _cnf._load_defaults()
337 2e616dbd Stavros Sachtouris
            for i, (section, options) in enumerate(DEFAULTS.items()):
338 2e616dbd Stavros Sachtouris
                for j, (option, val) in enumerate(options.items()):
339 2e616dbd Stavros Sachtouris
                    self.assertEqual(
340 2e616dbd Stavros Sachtouris
                        c_set.mock_calls[(i + 1) * j],
341 2e616dbd Stavros Sachtouris
                        call(section, option, val))
342 2e616dbd Stavros Sachtouris
343 2e616dbd Stavros Sachtouris
    def test__get_dict(self):
344 2e616dbd Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX, DEFAULTS
345 2e616dbd Stavros Sachtouris
346 2e616dbd Stavros Sachtouris
        def make_file(lines):
347 2e616dbd Stavros Sachtouris
            f = NamedTemporaryFile()
348 2e616dbd Stavros Sachtouris
            f.writelines(lines)
349 2e616dbd Stavros Sachtouris
            f.flush()
350 2e616dbd Stavros Sachtouris
            return f
351 2e616dbd Stavros Sachtouris
352 2e616dbd Stavros Sachtouris
        with make_file([]) as f:
353 2e616dbd Stavros Sachtouris
            _cnf = Config(path=f.name)
354 2e616dbd Stavros Sachtouris
            for term in ('global', CLOUD_PREFIX):
355 2e616dbd Stavros Sachtouris
                self.assertEqual(DEFAULTS[term], _cnf._get_dict(term))
356 2e616dbd Stavros Sachtouris
            for term in ('nosection', ''):
357 2e616dbd Stavros Sachtouris
                self.assertEqual({}, _cnf._get_dict(term))
358 2e616dbd Stavros Sachtouris
359 2e616dbd Stavros Sachtouris
        with make_file(self.config_file_content) as f:
360 2e616dbd Stavros Sachtouris
            _cnf = Config(path=f.name)
361 2e616dbd Stavros Sachtouris
            for term in ('global', CLOUD_PREFIX):
362 2e616dbd Stavros Sachtouris
                self.assertNotEqual(DEFAULTS[term], _cnf._get_dict(term))
363 2e616dbd Stavros Sachtouris
364 2e616dbd Stavros Sachtouris
    def test_reload(self):
365 2e616dbd Stavros Sachtouris
        from kamaki.cli.config import Config
366 2e616dbd Stavros Sachtouris
        _cnf = Config(path=self.f.name)
367 2e616dbd Stavros Sachtouris
368 2e616dbd Stavros Sachtouris
        with patch('kamaki.cli.config.Config.__init__') as i:
369 2e616dbd Stavros Sachtouris
            _cnf.reload()
370 2e616dbd Stavros Sachtouris
            i.assert_called_once_with(self.f.name)
371 2e616dbd Stavros Sachtouris
372 8556d269 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.get_cloud', return_value='get cloud')
373 8556d269 Stavros Sachtouris
    def test_get(self, get_cloud):
374 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
375 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
376 8556d269 Stavros Sachtouris
        self.assertEqual('pithos', _cnf.get('global', 'file_cli'))
377 8556d269 Stavros Sachtouris
        self.assertEqual(get_cloud.mock_calls, [])
378 8556d269 Stavros Sachtouris
        for opt, sec in (('cloud', 'non-existing'), ('non-opt', 'exists')):
379 8556d269 Stavros Sachtouris
            self.assertEqual(None, _cnf.get(opt, sec))
380 8556d269 Stavros Sachtouris
            self.assertEqual(get_cloud.mock_calls, [])
381 8556d269 Stavros Sachtouris
        self.assertEqual('get cloud', _cnf.get('cloud.demo', 'url'))
382 8556d269 Stavros Sachtouris
        self.assertEqual(get_cloud.mock_calls[-1], call('demo', 'url'))
383 8556d269 Stavros Sachtouris
384 8556d269 Stavros Sachtouris
    def test_set(self):
385 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX
386 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
387 8556d269 Stavros Sachtouris
388 8556d269 Stavros Sachtouris
        with patch(
389 8556d269 Stavros Sachtouris
                'kamaki.cli.config.Config._cloud_name',
390 8556d269 Stavros Sachtouris
                return_value='cn') as _cloud_name:
391 8556d269 Stavros Sachtouris
            with patch(
392 8556d269 Stavros Sachtouris
                    'kamaki.cli.config.Config.set_cloud',
393 8556d269 Stavros Sachtouris
                    return_value='sc') as set_cloud:
394 8556d269 Stavros Sachtouris
                self.assertEqual(
395 8556d269 Stavros Sachtouris
                    'sc', _cnf.set('%s.sec' % CLOUD_PREFIX, 'opt', 'val'))
396 8556d269 Stavros Sachtouris
                self.assertEqual(
397 8556d269 Stavros Sachtouris
                    _cloud_name.mock_calls[-1],
398 8556d269 Stavros Sachtouris
                    call('%s "sec"' % CLOUD_PREFIX))
399 8556d269 Stavros Sachtouris
                self.assertEqual(
400 8556d269 Stavros Sachtouris
                    set_cloud.mock_calls[-1], call('cn', 'opt', 'val'))
401 8556d269 Stavros Sachtouris
402 8556d269 Stavros Sachtouris
                self.assertTrue(len(_cnf.items('global')) > 0)
403 8556d269 Stavros Sachtouris
                self.assertEqual(None, _cnf.set('global', 'opt', 'val'))
404 8556d269 Stavros Sachtouris
                self.assertTrue(('opt', 'val') in _cnf.items('global'))
405 8556d269 Stavros Sachtouris
406 8556d269 Stavros Sachtouris
                self.assertTrue(len(_cnf.items('new')) == 0)
407 8556d269 Stavros Sachtouris
                self.assertEqual(None, _cnf.set('new', 'opt', 'val'))
408 8556d269 Stavros Sachtouris
                self.assertTrue(('opt', 'val') in _cnf.items('new'))
409 8556d269 Stavros Sachtouris
410 8556d269 Stavros Sachtouris
    def test_remove_option(self):
411 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
412 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
413 8556d269 Stavros Sachtouris
414 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('no-section')), 0)
415 8556d269 Stavros Sachtouris
        _cnf.remove_option('no-section', 'opt', False)
416 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('no-section')), 0)
417 8556d269 Stavros Sachtouris
        _cnf.remove_option('no-section', 'opt', True)
418 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('no-section')), 0)
419 8556d269 Stavros Sachtouris
420 8556d269 Stavros Sachtouris
        opt_num = len(_cnf.items('global'))
421 8556d269 Stavros Sachtouris
        self.assertTrue(opt_num > 0)
422 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'file_cli', False)
423 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('global')), opt_num)
424 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'file_cli', True)
425 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('global')), opt_num - 1)
426 8556d269 Stavros Sachtouris
427 8556d269 Stavros Sachtouris
        _cnf.set('global', 'server_cli', 'alt-server')
428 8556d269 Stavros Sachtouris
        self.assertTrue(('server_cli', 'alt-server') in _cnf.items('global'))
429 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'cyclades') in _cnf.items('global'))
430 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'server_cli', False)
431 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'alt-server') in _cnf.items('global'))
432 8556d269 Stavros Sachtouris
        self.assertTrue(('server_cli', 'cyclades') in _cnf.items('global'))
433 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'server_cli', True)
434 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'alt-server') in _cnf.items('global'))
435 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'cyclades') in _cnf.items('global'))
436 8556d269 Stavros Sachtouris
437 8556d269 Stavros Sachtouris
    def test_remove_from_cloud(self):
438 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX
439 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
440 8556d269 Stavros Sachtouris
441 8556d269 Stavros Sachtouris
        d = dict(k1='v1', k2='v2')
442 8556d269 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=d) as get:
443 8556d269 Stavros Sachtouris
            _cnf.remove_from_cloud('cld', 'k1')
444 8556d269 Stavros Sachtouris
            self.assertEqual(d, dict(k2='v2'))
445 8556d269 Stavros Sachtouris
            self.assertRaises(KeyError, _cnf.remove_from_cloud, 'cld', 'opt')
446 8556d269 Stavros Sachtouris
            self.assertEqual(get.mock_calls, 2 * [call(CLOUD_PREFIX, 'cld')])
447 8556d269 Stavros Sachtouris
448 8556d269 Stavros Sachtouris
    @patch(
449 8556d269 Stavros Sachtouris
        'kamaki.cli.config.Config._get_dict',
450 8556d269 Stavros Sachtouris
        return_value={'k1': 'v1', 'k2': 'v2'})
451 8556d269 Stavros Sachtouris
    def test_keys(self, _get_dict):
452 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
453 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
454 8556d269 Stavros Sachtouris
455 8556d269 Stavros Sachtouris
        self.assertEqual(
456 8556d269 Stavros Sachtouris
            sorted(['k1', 'k2']), sorted(_cnf.keys('opt', 'boolean')))
457 8556d269 Stavros Sachtouris
        _get_dict.assert_called_once_with('opt', 'boolean')
458 8556d269 Stavros Sachtouris
459 8556d269 Stavros Sachtouris
    @patch(
460 8556d269 Stavros Sachtouris
        'kamaki.cli.config.Config._get_dict',
461 8556d269 Stavros Sachtouris
        return_value={'k1': 'v1', 'k2': 'v2'})
462 8556d269 Stavros Sachtouris
    def test_items(self, _get_dict):
463 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
464 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
465 8556d269 Stavros Sachtouris
466 8556d269 Stavros Sachtouris
        self.assertEqual(
467 8556d269 Stavros Sachtouris
            sorted([('k1', 'v1'), ('k2', 'v2')]),
468 8556d269 Stavros Sachtouris
            sorted(_cnf.items('opt', 'boolean')))
469 8556d269 Stavros Sachtouris
        _get_dict.assert_called_once_with('opt', 'boolean')
470 8556d269 Stavros Sachtouris
471 8556d269 Stavros Sachtouris
    def test_override(self):
472 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
473 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
474 8556d269 Stavros Sachtouris
475 8556d269 Stavros Sachtouris
        _cnf.override('sec', 'opt', 'val')
476 8556d269 Stavros Sachtouris
        self.assertEqual(_cnf._overrides['sec']['opt'], 'val')
477 8556d269 Stavros Sachtouris
478 8556d269 Stavros Sachtouris
    def test_write(self):
479 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config, DEFAULTS
480 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
481 8556d269 Stavros Sachtouris
482 8556d269 Stavros Sachtouris
        exp = '%s[global]\n' % HEADER
483 8556d269 Stavros Sachtouris
        exp += ''.join([
484 8556d269 Stavros Sachtouris
            '%s = %s\n' % (k, v) for k, v in DEFAULTS['global'].items()])
485 8556d269 Stavros Sachtouris
        exp += '\n'
486 8556d269 Stavros Sachtouris
487 8556d269 Stavros Sachtouris
        _cnf.write()
488 8556d269 Stavros Sachtouris
        self.f.seek(0)
489 8556d269 Stavros Sachtouris
        self.assertEqual(self.f.read(), exp)
490 8556d269 Stavros Sachtouris
491 8556d269 Stavros Sachtouris
        del _cnf
492 8556d269 Stavros Sachtouris
        with NamedTemporaryFile() as f:
493 8556d269 Stavros Sachtouris
            f.write('\n'.join(self.config_file_content))
494 8556d269 Stavros Sachtouris
            f.flush()
495 8556d269 Stavros Sachtouris
            _cnf = Config(path=f.name)
496 8556d269 Stavros Sachtouris
            f.seek(0)
497 8556d269 Stavros Sachtouris
            self.assertEqual(f.read(), '\n'.join(self.config_file_content))
498 8556d269 Stavros Sachtouris
            _cnf.write()
499 8556d269 Stavros Sachtouris
            f.seek(0)
500 8556d269 Stavros Sachtouris
            file_contents = f.read()
501 8556d269 Stavros Sachtouris
            for line in self.config_file_content:
502 8556d269 Stavros Sachtouris
                self.assertTrue(line in file_contents)
503 8556d269 Stavros Sachtouris
            _cnf.set('sec', 'opt', 'val')
504 8556d269 Stavros Sachtouris
            _cnf.set('global', 'opt', 'val')
505 8556d269 Stavros Sachtouris
            _cnf.set('global', 'file_cli', 'val')
506 8556d269 Stavros Sachtouris
            _cnf.write()
507 8556d269 Stavros Sachtouris
            f.seek(0)
508 8556d269 Stavros Sachtouris
            file_contents = f.read()
509 8556d269 Stavros Sachtouris
            for line in ('file_cli = val\n', '[sec]\n', 'opt = val\n'):
510 8556d269 Stavros Sachtouris
                self.assertTrue(line in file_contents)
511 8556d269 Stavros Sachtouris
512 9f5cbafe Stavros Sachtouris
513 9f5cbafe Stavros Sachtouris
if __name__ == '__main__':
514 9f5cbafe Stavros Sachtouris
    from sys import argv
515 9f5cbafe Stavros Sachtouris
    from kamaki.cli.test import runTestCase
516 f767b407 Stavros Sachtouris
    runTestCase(Config, 'Config', argv[1:])