Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / config / test.py @ 6489c38b

History | View | Annotate | Download (20.5 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
    def test_get_global(self):
304 3564be49 Stavros Sachtouris
        from kamaki.cli.config import Config
305 3564be49 Stavros Sachtouris
306 3564be49 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
307 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value='val') as get:
308 3564be49 Stavros Sachtouris
            self.assertEqual('val', _cnf.get_global('opt'))
309 3564be49 Stavros Sachtouris
            get.assert_called_once_with('global', 'opt')
310 3564be49 Stavros Sachtouris
311 3564be49 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.set')
312 3564be49 Stavros Sachtouris
    def test_set_cloud(self, c_set):
313 3564be49 Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX
314 3564be49 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
315 3564be49 Stavros Sachtouris
316 3564be49 Stavros Sachtouris
        d = dict(k='v')
317 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=d) as get:
318 3564be49 Stavros Sachtouris
            _cnf.set_cloud('mycloud', 'opt', 'val')
319 3564be49 Stavros Sachtouris
            get.assert_called_once_with(CLOUD_PREFIX, 'mycloud')
320 3564be49 Stavros Sachtouris
            d['opt'] = 'val'
321 3564be49 Stavros Sachtouris
            self.assertEqual(
322 3564be49 Stavros Sachtouris
                c_set.mock_calls[-1], call(CLOUD_PREFIX, 'mycloud', d))
323 3564be49 Stavros Sachtouris
324 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=None) 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 3564be49 Stavros Sachtouris
        with patch(
332 3564be49 Stavros Sachtouris
                'kamaki.cli.config.Config.get', side_effect=KeyError()) as get:
333 3564be49 Stavros Sachtouris
            _cnf.set_cloud('mycloud', 'opt', 'val')
334 3564be49 Stavros Sachtouris
            get.assert_called_once_with(CLOUD_PREFIX, 'mycloud')
335 3564be49 Stavros Sachtouris
            d = dict(opt='val')
336 3564be49 Stavros Sachtouris
            self.assertEqual(
337 3564be49 Stavros Sachtouris
                c_set.mock_calls[-1], call(CLOUD_PREFIX, 'mycloud', d))
338 3564be49 Stavros Sachtouris
339 3564be49 Stavros Sachtouris
    def test_set_global(self):
340 3564be49 Stavros Sachtouris
        from kamaki.cli.config import Config
341 3564be49 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
342 3564be49 Stavros Sachtouris
343 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.set') as c_set:
344 3564be49 Stavros Sachtouris
            _cnf.set_global('opt', 'val')
345 3564be49 Stavros Sachtouris
            c_set.assert_called_once_with('global', 'opt', 'val')
346 3564be49 Stavros Sachtouris
347 2e616dbd Stavros Sachtouris
    def test__load_defaults(self):
348 2e616dbd Stavros Sachtouris
        from kamaki.cli.config import Config, DEFAULTS
349 2e616dbd Stavros Sachtouris
        _cnf = Config(path=self.f.name)
350 2e616dbd Stavros Sachtouris
351 2e616dbd Stavros Sachtouris
        with patch('kamaki.cli.config.Config.set') as c_set:
352 2e616dbd Stavros Sachtouris
            _cnf._load_defaults()
353 2e616dbd Stavros Sachtouris
            for i, (section, options) in enumerate(DEFAULTS.items()):
354 2e616dbd Stavros Sachtouris
                for j, (option, val) in enumerate(options.items()):
355 2e616dbd Stavros Sachtouris
                    self.assertEqual(
356 2e616dbd Stavros Sachtouris
                        c_set.mock_calls[(i + 1) * j],
357 2e616dbd Stavros Sachtouris
                        call(section, option, val))
358 2e616dbd Stavros Sachtouris
359 2e616dbd Stavros Sachtouris
    def test__get_dict(self):
360 2e616dbd Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX, DEFAULTS
361 2e616dbd Stavros Sachtouris
362 2e616dbd Stavros Sachtouris
        def make_file(lines):
363 2e616dbd Stavros Sachtouris
            f = NamedTemporaryFile()
364 2e616dbd Stavros Sachtouris
            f.writelines(lines)
365 2e616dbd Stavros Sachtouris
            f.flush()
366 2e616dbd Stavros Sachtouris
            return f
367 2e616dbd Stavros Sachtouris
368 2e616dbd Stavros Sachtouris
        with make_file([]) as f:
369 2e616dbd Stavros Sachtouris
            _cnf = Config(path=f.name)
370 2e616dbd Stavros Sachtouris
            for term in ('global', CLOUD_PREFIX):
371 2e616dbd Stavros Sachtouris
                self.assertEqual(DEFAULTS[term], _cnf._get_dict(term))
372 2e616dbd Stavros Sachtouris
            for term in ('nosection', ''):
373 2e616dbd Stavros Sachtouris
                self.assertEqual({}, _cnf._get_dict(term))
374 2e616dbd Stavros Sachtouris
375 2e616dbd Stavros Sachtouris
        with make_file(self.config_file_content) as f:
376 2e616dbd Stavros Sachtouris
            _cnf = Config(path=f.name)
377 2e616dbd Stavros Sachtouris
            for term in ('global', CLOUD_PREFIX):
378 2e616dbd Stavros Sachtouris
                self.assertNotEqual(DEFAULTS[term], _cnf._get_dict(term))
379 2e616dbd Stavros Sachtouris
380 2e616dbd Stavros Sachtouris
    def test_reload(self):
381 2e616dbd Stavros Sachtouris
        from kamaki.cli.config import Config
382 2e616dbd Stavros Sachtouris
        _cnf = Config(path=self.f.name)
383 2e616dbd Stavros Sachtouris
384 2e616dbd Stavros Sachtouris
        with patch('kamaki.cli.config.Config.__init__') as i:
385 2e616dbd Stavros Sachtouris
            _cnf.reload()
386 2e616dbd Stavros Sachtouris
            i.assert_called_once_with(self.f.name)
387 2e616dbd Stavros Sachtouris
388 8556d269 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.get_cloud', return_value='get cloud')
389 8556d269 Stavros Sachtouris
    def test_get(self, get_cloud):
390 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
391 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
392 8556d269 Stavros Sachtouris
        self.assertEqual('pithos', _cnf.get('global', 'file_cli'))
393 8556d269 Stavros Sachtouris
        self.assertEqual(get_cloud.mock_calls, [])
394 8556d269 Stavros Sachtouris
        for opt, sec in (('cloud', 'non-existing'), ('non-opt', 'exists')):
395 8556d269 Stavros Sachtouris
            self.assertEqual(None, _cnf.get(opt, sec))
396 8556d269 Stavros Sachtouris
            self.assertEqual(get_cloud.mock_calls, [])
397 8556d269 Stavros Sachtouris
        self.assertEqual('get cloud', _cnf.get('cloud.demo', 'url'))
398 8556d269 Stavros Sachtouris
        self.assertEqual(get_cloud.mock_calls[-1], call('demo', 'url'))
399 8556d269 Stavros Sachtouris
400 8556d269 Stavros Sachtouris
    def test_set(self):
401 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX
402 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
403 8556d269 Stavros Sachtouris
404 8556d269 Stavros Sachtouris
        with patch(
405 8556d269 Stavros Sachtouris
                'kamaki.cli.config.Config._cloud_name',
406 8556d269 Stavros Sachtouris
                return_value='cn') as _cloud_name:
407 8556d269 Stavros Sachtouris
            with patch(
408 8556d269 Stavros Sachtouris
                    'kamaki.cli.config.Config.set_cloud',
409 8556d269 Stavros Sachtouris
                    return_value='sc') as set_cloud:
410 8556d269 Stavros Sachtouris
                self.assertEqual(
411 8556d269 Stavros Sachtouris
                    'sc', _cnf.set('%s.sec' % CLOUD_PREFIX, 'opt', 'val'))
412 8556d269 Stavros Sachtouris
                self.assertEqual(
413 8556d269 Stavros Sachtouris
                    _cloud_name.mock_calls[-1],
414 8556d269 Stavros Sachtouris
                    call('%s "sec"' % CLOUD_PREFIX))
415 8556d269 Stavros Sachtouris
                self.assertEqual(
416 8556d269 Stavros Sachtouris
                    set_cloud.mock_calls[-1], call('cn', 'opt', 'val'))
417 8556d269 Stavros Sachtouris
418 8556d269 Stavros Sachtouris
                self.assertTrue(len(_cnf.items('global')) > 0)
419 8556d269 Stavros Sachtouris
                self.assertEqual(None, _cnf.set('global', 'opt', 'val'))
420 8556d269 Stavros Sachtouris
                self.assertTrue(('opt', 'val') in _cnf.items('global'))
421 8556d269 Stavros Sachtouris
422 8556d269 Stavros Sachtouris
                self.assertTrue(len(_cnf.items('new')) == 0)
423 8556d269 Stavros Sachtouris
                self.assertEqual(None, _cnf.set('new', 'opt', 'val'))
424 8556d269 Stavros Sachtouris
                self.assertTrue(('opt', 'val') in _cnf.items('new'))
425 8556d269 Stavros Sachtouris
426 8556d269 Stavros Sachtouris
    def test_remove_option(self):
427 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
428 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
429 8556d269 Stavros Sachtouris
430 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('no-section')), 0)
431 8556d269 Stavros Sachtouris
        _cnf.remove_option('no-section', 'opt', False)
432 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('no-section')), 0)
433 8556d269 Stavros Sachtouris
        _cnf.remove_option('no-section', 'opt', True)
434 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('no-section')), 0)
435 8556d269 Stavros Sachtouris
436 8556d269 Stavros Sachtouris
        opt_num = len(_cnf.items('global'))
437 8556d269 Stavros Sachtouris
        self.assertTrue(opt_num > 0)
438 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'file_cli', False)
439 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('global')), opt_num)
440 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'file_cli', True)
441 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('global')), opt_num - 1)
442 8556d269 Stavros Sachtouris
443 8556d269 Stavros Sachtouris
        _cnf.set('global', 'server_cli', 'alt-server')
444 8556d269 Stavros Sachtouris
        self.assertTrue(('server_cli', 'alt-server') in _cnf.items('global'))
445 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'cyclades') in _cnf.items('global'))
446 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'server_cli', False)
447 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'alt-server') in _cnf.items('global'))
448 8556d269 Stavros Sachtouris
        self.assertTrue(('server_cli', 'cyclades') in _cnf.items('global'))
449 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'server_cli', True)
450 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'alt-server') in _cnf.items('global'))
451 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'cyclades') in _cnf.items('global'))
452 8556d269 Stavros Sachtouris
453 8556d269 Stavros Sachtouris
    def test_remove_from_cloud(self):
454 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX
455 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
456 8556d269 Stavros Sachtouris
457 8556d269 Stavros Sachtouris
        d = dict(k1='v1', k2='v2')
458 8556d269 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=d) as get:
459 8556d269 Stavros Sachtouris
            _cnf.remove_from_cloud('cld', 'k1')
460 8556d269 Stavros Sachtouris
            self.assertEqual(d, dict(k2='v2'))
461 8556d269 Stavros Sachtouris
            self.assertRaises(KeyError, _cnf.remove_from_cloud, 'cld', 'opt')
462 8556d269 Stavros Sachtouris
            self.assertEqual(get.mock_calls, 2 * [call(CLOUD_PREFIX, 'cld')])
463 8556d269 Stavros Sachtouris
464 8556d269 Stavros Sachtouris
    @patch(
465 8556d269 Stavros Sachtouris
        'kamaki.cli.config.Config._get_dict',
466 8556d269 Stavros Sachtouris
        return_value={'k1': 'v1', 'k2': 'v2'})
467 8556d269 Stavros Sachtouris
    def test_keys(self, _get_dict):
468 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
469 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
470 8556d269 Stavros Sachtouris
471 8556d269 Stavros Sachtouris
        self.assertEqual(
472 8556d269 Stavros Sachtouris
            sorted(['k1', 'k2']), sorted(_cnf.keys('opt', 'boolean')))
473 8556d269 Stavros Sachtouris
        _get_dict.assert_called_once_with('opt', 'boolean')
474 8556d269 Stavros Sachtouris
475 8556d269 Stavros Sachtouris
    @patch(
476 8556d269 Stavros Sachtouris
        'kamaki.cli.config.Config._get_dict',
477 8556d269 Stavros Sachtouris
        return_value={'k1': 'v1', 'k2': 'v2'})
478 8556d269 Stavros Sachtouris
    def test_items(self, _get_dict):
479 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
480 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
481 8556d269 Stavros Sachtouris
482 8556d269 Stavros Sachtouris
        self.assertEqual(
483 8556d269 Stavros Sachtouris
            sorted([('k1', 'v1'), ('k2', 'v2')]),
484 8556d269 Stavros Sachtouris
            sorted(_cnf.items('opt', 'boolean')))
485 8556d269 Stavros Sachtouris
        _get_dict.assert_called_once_with('opt', 'boolean')
486 8556d269 Stavros Sachtouris
487 8556d269 Stavros Sachtouris
    def test_override(self):
488 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
489 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
490 8556d269 Stavros Sachtouris
491 8556d269 Stavros Sachtouris
        _cnf.override('sec', 'opt', 'val')
492 8556d269 Stavros Sachtouris
        self.assertEqual(_cnf._overrides['sec']['opt'], 'val')
493 8556d269 Stavros Sachtouris
494 8556d269 Stavros Sachtouris
    def test_write(self):
495 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config, DEFAULTS
496 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
497 8556d269 Stavros Sachtouris
498 8556d269 Stavros Sachtouris
        exp = '%s[global]\n' % HEADER
499 8556d269 Stavros Sachtouris
        exp += ''.join([
500 8556d269 Stavros Sachtouris
            '%s = %s\n' % (k, v) for k, v in DEFAULTS['global'].items()])
501 8556d269 Stavros Sachtouris
        exp += '\n'
502 8556d269 Stavros Sachtouris
503 8556d269 Stavros Sachtouris
        _cnf.write()
504 8556d269 Stavros Sachtouris
        self.f.seek(0)
505 8556d269 Stavros Sachtouris
        self.assertEqual(self.f.read(), exp)
506 8556d269 Stavros Sachtouris
507 8556d269 Stavros Sachtouris
        del _cnf
508 8556d269 Stavros Sachtouris
        with NamedTemporaryFile() as f:
509 8556d269 Stavros Sachtouris
            f.write('\n'.join(self.config_file_content))
510 8556d269 Stavros Sachtouris
            f.flush()
511 8556d269 Stavros Sachtouris
            _cnf = Config(path=f.name)
512 8556d269 Stavros Sachtouris
            f.seek(0)
513 8556d269 Stavros Sachtouris
            self.assertEqual(f.read(), '\n'.join(self.config_file_content))
514 8556d269 Stavros Sachtouris
            _cnf.write()
515 8556d269 Stavros Sachtouris
            f.seek(0)
516 8556d269 Stavros Sachtouris
            file_contents = f.read()
517 8556d269 Stavros Sachtouris
            for line in self.config_file_content:
518 8556d269 Stavros Sachtouris
                self.assertTrue(line in file_contents)
519 8556d269 Stavros Sachtouris
            _cnf.set('sec', 'opt', 'val')
520 8556d269 Stavros Sachtouris
            _cnf.set('global', 'opt', 'val')
521 8556d269 Stavros Sachtouris
            _cnf.set('global', 'file_cli', 'val')
522 8556d269 Stavros Sachtouris
            _cnf.write()
523 8556d269 Stavros Sachtouris
            f.seek(0)
524 8556d269 Stavros Sachtouris
            file_contents = f.read()
525 8556d269 Stavros Sachtouris
            for line in ('file_cli = val\n', '[sec]\n', 'opt = val\n'):
526 8556d269 Stavros Sachtouris
                self.assertTrue(line in file_contents)
527 8556d269 Stavros Sachtouris
528 9f5cbafe Stavros Sachtouris
529 9f5cbafe Stavros Sachtouris
if __name__ == '__main__':
530 9f5cbafe Stavros Sachtouris
    from sys import argv
531 9f5cbafe Stavros Sachtouris
    from kamaki.cli.test import runTestCase
532 f767b407 Stavros Sachtouris
    runTestCase(Config, 'Config', argv[1:])