Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / config / test.py @ 38a79780

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
            'default_cloud = ~mycloud\n',
72 8556d269 Stavros Sachtouris
            'file_cli = pithos\n',
73 8556d269 Stavros Sachtouris
            'history_file = /home/user/.kamaki.history\n',
74 8556d269 Stavros Sachtouris
            'colors = off\n',
75 8556d269 Stavros Sachtouris
            'config_cli = config\n',
76 8556d269 Stavros Sachtouris
            'history_cli = history\n',
77 8556d269 Stavros Sachtouris
            'log_token = off\n',
78 8556d269 Stavros Sachtouris
            'server_cli = cyclades\n',
79 8556d269 Stavros Sachtouris
            'user_cli = astakos\n',
80 8556d269 Stavros Sachtouris
            'log_data = off\n',
81 8556d269 Stavros Sachtouris
            'flavor_cli = cyclades\n',
82 8556d269 Stavros Sachtouris
            'image_cli = image\n',
83 8556d269 Stavros Sachtouris
            'log_file = /home/user/.kamaki.log\n',
84 8556d269 Stavros Sachtouris
            'network_cli = cyclades\n',
85 8556d269 Stavros Sachtouris
            'log_pid = off\n',
86 8556d269 Stavros Sachtouris
            '\n',
87 8556d269 Stavros Sachtouris
            '[cloud "demo"]\n',
88 8556d269 Stavros Sachtouris
            'url = https://demo.example.com\n',
89 8556d269 Stavros Sachtouris
            'token = t0k3n-0f-d3m0-3x4mp13\n',
90 8556d269 Stavros Sachtouris
            '\n',
91 8556d269 Stavros Sachtouris
            '[cloud "~mycloud"]\n',
92 8556d269 Stavros Sachtouris
            'url = https://example.com\n',
93 8556d269 Stavros Sachtouris
            'pithos_container = images\n']
94 8556d269 Stavros Sachtouris
95 8556d269 Stavros Sachtouris
    def tearDown(self):
96 3564be49 Stavros Sachtouris
        try:
97 3564be49 Stavros Sachtouris
            self.f.close()
98 3564be49 Stavros Sachtouris
        except Exception:
99 3564be49 Stavros Sachtouris
            pass
100 8556d269 Stavros Sachtouris
        finally:
101 8556d269 Stavros Sachtouris
            from kamaki.cli.config import DEFAULTS
102 8556d269 Stavros Sachtouris
            keys = DEFAULTS.keys()
103 8556d269 Stavros Sachtouris
            for k in keys:
104 8556d269 Stavros Sachtouris
                DEFAULTS.pop(k)
105 8556d269 Stavros Sachtouris
            for k, v in self.DEFAULTS.items():
106 8556d269 Stavros Sachtouris
                DEFAULTS[k] = v
107 3564be49 Stavros Sachtouris
108 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.remove_section')
109 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.items', return_value=(
110 f767b407 Stavros Sachtouris
        ('k1', 'v1'), ('k2', 'v2')))
111 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.sections', return_value=('a', 'b'))
112 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.set_cloud')
113 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.read')
114 f767b407 Stavros Sachtouris
    @patch('kamaki.cli.config.Config._load_defaults')
115 f767b407 Stavros Sachtouris
    def test___init__(
116 f767b407 Stavros Sachtouris
            self, _ld, c_read, c_set_cloud, c_sections, c_items,
117 f767b407 Stavros Sachtouris
            c_remove_section):
118 f767b407 Stavros Sachtouris
        from kamaki.cli.config import (
119 f767b407 Stavros Sachtouris
            Config, RawConfigParser, CONFIG_ENV, CONFIG_PATH)
120 f767b407 Stavros Sachtouris
        _ld_num, c_sections_num, c_items_num, c_set_cloud_num = 0, 0, 0, 0
121 f767b407 Stavros Sachtouris
        c_remove_section_num, gen_call = 0, [call('a'), call('b')]
122 f767b407 Stavros Sachtouris
        for path, with_defaults in product((None, '/a/path'), (True, False)):
123 f767b407 Stavros Sachtouris
            with patch(
124 f767b407 Stavros Sachtouris
                    'kamaki.cli.config.Config._cloud_name',
125 f767b407 Stavros Sachtouris
                    return_value=_2value_gen.next()) as _cloud_name:
126 f767b407 Stavros Sachtouris
                cnf = Config(path=path, with_defaults=with_defaults)
127 f767b407 Stavros Sachtouris
                self.assertTrue(isinstance(cnf, RawConfigParser))
128 f767b407 Stavros Sachtouris
                cpath = path or os.environ.get(CONFIG_ENV, CONFIG_PATH)
129 f767b407 Stavros Sachtouris
                self.assertEqual(cnf.path, cpath)
130 f767b407 Stavros Sachtouris
                if with_defaults:
131 f767b407 Stavros Sachtouris
                    _ld_num += 1
132 f767b407 Stavros Sachtouris
                    self.assertEqual(_ld.mock_calls[-1], call())
133 f767b407 Stavros Sachtouris
                self.assertEqual(len(_ld.mock_calls), _ld_num)
134 f767b407 Stavros Sachtouris
                self.assertEqual(c_read.mock_calls[-1], call(cpath))
135 f767b407 Stavros Sachtouris
136 f767b407 Stavros Sachtouris
                c_sections_num += 1
137 f767b407 Stavros Sachtouris
                self.assertEqual(len(c_sections.mock_calls), c_sections_num)
138 f767b407 Stavros Sachtouris
                self.assertEqual(c_sections.mock_calls[-1], call())
139 f767b407 Stavros Sachtouris
140 f767b407 Stavros Sachtouris
                self.assertEqual(_cloud_name.mock_calls, gen_call)
141 f767b407 Stavros Sachtouris
142 f767b407 Stavros Sachtouris
                r = _2value_gen.next()
143 f767b407 Stavros Sachtouris
                if r:
144 f767b407 Stavros Sachtouris
                    c_items_num += 2
145 f767b407 Stavros Sachtouris
                    self.assertEqual(c_items.mock_calls[-2:], gen_call)
146 f767b407 Stavros Sachtouris
                    c_set_cloud_num += 4
147 f767b407 Stavros Sachtouris
                    self.assertEqual(c_set_cloud.mock_calls[-4:], [
148 c5997814 Stavros Sachtouris
                        call(r, 'k1', 'v1'), call(r, 'k2', 'v2')] * 2)
149 f767b407 Stavros Sachtouris
                    c_remove_section_num += 2
150 f767b407 Stavros Sachtouris
                    self.assertEqual(
151 f767b407 Stavros Sachtouris
                        c_remove_section.mock_calls[-2:], gen_call)
152 f767b407 Stavros Sachtouris
                self.assertEqual(len(c_items.mock_calls), c_items_num)
153 f767b407 Stavros Sachtouris
                self.assertEqual(len(c_set_cloud.mock_calls), c_set_cloud_num)
154 f767b407 Stavros Sachtouris
                self.assertEqual(
155 f767b407 Stavros Sachtouris
                    len(c_remove_section.mock_calls), c_remove_section_num)
156 9f5cbafe Stavros Sachtouris
157 c5997814 Stavros Sachtouris
    def test__cloud_name(self):
158 c5997814 Stavros Sachtouris
        from kamaki.cli.config import (
159 c5997814 Stavros Sachtouris
            Config, CLOUD_PREFIX, InvalidCloudNameError)
160 c5997814 Stavros Sachtouris
        cn = Config._cloud_name
161 c5997814 Stavros Sachtouris
        self.assertEqual(cn('non%s name' % CLOUD_PREFIX), None)
162 c5997814 Stavros Sachtouris
        for invalid in ('"!@#$%^&())_"', '"a b c"', u'"\xce\xcd"', 'naked'):
163 c5997814 Stavros Sachtouris
            self.assertRaises(
164 c5997814 Stavros Sachtouris
                InvalidCloudNameError, cn, '%s %s' % (CLOUD_PREFIX, invalid))
165 c5997814 Stavros Sachtouris
        for valid in ('word', '~okeanos', 'd0t.ted', 'ha$h#ed'):
166 c5997814 Stavros Sachtouris
            self.assertEqual(cn('%s "%s"' % (CLOUD_PREFIX, valid)), valid)
167 c5997814 Stavros Sachtouris
168 c5997814 Stavros Sachtouris
    def test_rescue_old_file(self):
169 c5997814 Stavros Sachtouris
        from kamaki.cli.config import Config
170 3564be49 Stavros Sachtouris
171 3564be49 Stavros Sachtouris
        content0 = list(self.config_file_content)
172 c5997814 Stavros Sachtouris
173 c5997814 Stavros Sachtouris
        def make_file(lines):
174 c5997814 Stavros Sachtouris
            f = NamedTemporaryFile()
175 c5997814 Stavros Sachtouris
            f.writelines(lines)
176 c5997814 Stavros Sachtouris
            f.flush()
177 c5997814 Stavros Sachtouris
            return f
178 c5997814 Stavros Sachtouris
179 c5997814 Stavros Sachtouris
        with make_file(content0) as f:
180 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
181 c5997814 Stavros Sachtouris
            self.assertEqual([], _cnf.rescue_old_file())
182 c5997814 Stavros Sachtouris
        del _cnf
183 c5997814 Stavros Sachtouris
184 c5997814 Stavros Sachtouris
        content1, sample = list(content0), 'xyz_cli = XYZ_specs'
185 c5997814 Stavros Sachtouris
        content1.insert(2, '%s\n' % sample)
186 c5997814 Stavros Sachtouris
187 c5997814 Stavros Sachtouris
        with make_file(content1) as f:
188 8556d269 Stavros Sachtouris
            f.seek(0)
189 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
190 8556d269 Stavros Sachtouris
            self.assertEqual(
191 8556d269 Stavros Sachtouris
                sorted(['global.%s' % sample]), sorted(_cnf.rescue_old_file()))
192 c5997814 Stavros Sachtouris
        del _cnf
193 c5997814 Stavros Sachtouris
194 c5997814 Stavros Sachtouris
        content2, sample = list(content0), 'http://www.example2.org'
195 c5997814 Stavros Sachtouris
        content2.insert(2, 'url = %s\n' % sample)
196 c5997814 Stavros Sachtouris
        err = StringIO()
197 c5997814 Stavros Sachtouris
198 c5997814 Stavros Sachtouris
        with make_file(content2) as f:
199 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
200 c5997814 Stavros Sachtouris
            self.assertEqual([], _cnf.rescue_old_file(err=err))
201 c5997814 Stavros Sachtouris
            self.assertEqual(
202 c5997814 Stavros Sachtouris
                '... rescue global.url => cloud.default.url\n', err.getvalue())
203 c5997814 Stavros Sachtouris
            self.assertEqual(sample, _cnf.get_cloud('default', 'url'))
204 c5997814 Stavros Sachtouris
        del _cnf
205 c5997814 Stavros Sachtouris
206 c5997814 Stavros Sachtouris
        content3 = list(content0)
207 c5997814 Stavros Sachtouris
        content3.insert(
208 c5997814 Stavros Sachtouris
            2, 'url = http://example1.com\nurl = http://example2.com\n')
209 c5997814 Stavros Sachtouris
210 c5997814 Stavros Sachtouris
        with make_file(content3) as f:
211 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
212 c5997814 Stavros Sachtouris
            self.assertEqual([], _cnf.rescue_old_file(err=err))
213 c5997814 Stavros Sachtouris
            self.assertEqual(
214 c5997814 Stavros Sachtouris
                2 * '... rescue global.url => cloud.default.url\n',
215 c5997814 Stavros Sachtouris
                err.getvalue())
216 c5997814 Stavros Sachtouris
            self.assertEqual(
217 c5997814 Stavros Sachtouris
                'http://example2.com', _cnf.get_cloud('default', 'url'))
218 c5997814 Stavros Sachtouris
        del _cnf
219 c5997814 Stavros Sachtouris
220 c5997814 Stavros Sachtouris
        content4 = list(content0)
221 c5997814 Stavros Sachtouris
        content4.insert(2, 'url = http://example1.com\n')
222 c5997814 Stavros Sachtouris
        content4.append('\n[cloud "default"]\nurl=http://example2.com\n')
223 c5997814 Stavros Sachtouris
224 c5997814 Stavros Sachtouris
        with make_file(content4) as f:
225 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
226 c5997814 Stavros Sachtouris
            from kamaki.cli.errors import CLISyntaxError
227 c5997814 Stavros Sachtouris
            self.assertRaises(CLISyntaxError, _cnf.rescue_old_file)
228 c5997814 Stavros Sachtouris
        del _cnf
229 c5997814 Stavros Sachtouris
230 c5997814 Stavros Sachtouris
        content5 = list(content0)
231 c5997814 Stavros Sachtouris
        extras = [
232 c5997814 Stavros Sachtouris
            ('pithos_cli', 'pithos'), ('store_cli', 'pithos'),
233 c5997814 Stavros Sachtouris
            ('storage_cli', 'pithos'), ('compute_cli', 'cyclades'),
234 c5997814 Stavros Sachtouris
            ('cyclades_cli', 'cyclades')]
235 c5997814 Stavros Sachtouris
        for sample in extras:
236 c5997814 Stavros Sachtouris
            content5.insert(2, '%s = %s\n' % sample)
237 c5997814 Stavros Sachtouris
238 c5997814 Stavros Sachtouris
        with make_file(content5) as f:
239 c5997814 Stavros Sachtouris
            _cnf = Config(path=f.name)
240 c5997814 Stavros Sachtouris
            self.assertEqual(
241 c5997814 Stavros Sachtouris
                sorted(['global.%s = %s' % sample for sample in extras]),
242 c5997814 Stavros Sachtouris
                 sorted(_cnf.rescue_old_file()))
243 c5997814 Stavros Sachtouris
244 3564be49 Stavros Sachtouris
    def test_guess_version(self):
245 3564be49 Stavros Sachtouris
        from kamaki.cli.config import Config
246 3564be49 Stavros Sachtouris
        from kamaki.cli.logger import add_file_logger
247 3564be49 Stavros Sachtouris
248 3564be49 Stavros Sachtouris
        def make_log_file():
249 3564be49 Stavros Sachtouris
            f = NamedTemporaryFile()
250 3564be49 Stavros Sachtouris
            add_file_logger('kamaki.cli.config', filename=f.name)
251 3564be49 Stavros Sachtouris
            return f
252 3564be49 Stavros Sachtouris
253 3564be49 Stavros Sachtouris
        def make_file(lines):
254 3564be49 Stavros Sachtouris
            f = NamedTemporaryFile()
255 3564be49 Stavros Sachtouris
            f.writelines(lines)
256 3564be49 Stavros Sachtouris
            f.flush()
257 3564be49 Stavros Sachtouris
            return f
258 3564be49 Stavros Sachtouris
259 3564be49 Stavros Sachtouris
        with make_file([]) as f:
260 3564be49 Stavros Sachtouris
            with make_log_file() as logf:
261 3564be49 Stavros Sachtouris
                _cnf = Config(path=f.name)
262 3564be49 Stavros Sachtouris
                self.assertEqual(0.9, _cnf.guess_version())
263 3564be49 Stavros Sachtouris
                exp = 'All heuristics failed, cannot decide\n'
264 3564be49 Stavros Sachtouris
                logf.file.seek(- len(exp), 2)
265 3564be49 Stavros Sachtouris
                self.assertEqual(exp, logf.read())
266 3564be49 Stavros Sachtouris
267 3564be49 Stavros Sachtouris
        content0 = list(self.config_file_content)
268 3564be49 Stavros Sachtouris
269 3564be49 Stavros Sachtouris
        with make_file(content0) as f:
270 3564be49 Stavros Sachtouris
            with make_log_file() as logf:
271 3564be49 Stavros Sachtouris
                _cnf = Config(path=f.name)
272 3564be49 Stavros Sachtouris
                self.assertEqual(0.9, _cnf.guess_version())
273 3564be49 Stavros Sachtouris
                exp = '... found cloud "demo"\n'
274 3564be49 Stavros Sachtouris
                logf.seek(- len(exp), 2)
275 3564be49 Stavros Sachtouris
                self.assertEqual(exp, logf.read())
276 3564be49 Stavros Sachtouris
277 3564be49 Stavros Sachtouris
        for term in ('url', 'token'):
278 3564be49 Stavros Sachtouris
            content1 = list(content0)
279 3564be49 Stavros Sachtouris
            content1.insert(2, '%s = some_value' % term)
280 3564be49 Stavros Sachtouris
281 3564be49 Stavros Sachtouris
            with make_file(content1) as f:
282 3564be49 Stavros Sachtouris
                with make_log_file() as logf:
283 3564be49 Stavros Sachtouris
                    _cnf = Config(path=f.name)
284 3564be49 Stavros Sachtouris
                    self.assertEqual(0.8, _cnf.guess_version())
285 3564be49 Stavros Sachtouris
                    exp = '..... config file has an old global section\n'
286 3564be49 Stavros Sachtouris
                    logf.seek(- len(exp), 2)
287 3564be49 Stavros Sachtouris
                    self.assertEqual(exp, logf.read())
288 3564be49 Stavros Sachtouris
289 3564be49 Stavros Sachtouris
    def test_get_cloud(self):
290 3564be49 Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX
291 3564be49 Stavros Sachtouris
292 3564be49 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
293 3564be49 Stavros Sachtouris
        d = dict(opt1='v1', opt2='v2')
294 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=d) as get:
295 3564be49 Stavros Sachtouris
            self.assertEqual('v1', _cnf.get_cloud('mycloud', 'opt1'))
296 3564be49 Stavros Sachtouris
            self.assertEqual(
297 3564be49 Stavros Sachtouris
                get.mock_calls[-1], call(CLOUD_PREFIX, 'mycloud'))
298 3564be49 Stavros Sachtouris
            self.assertRaises(KeyError, _cnf.get_cloud, 'mycloud', 'opt3')
299 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=0) as get:
300 3564be49 Stavros Sachtouris
            self.assertRaises(KeyError, _cnf.get_cloud, 'mycloud', 'opt1')
301 3564be49 Stavros Sachtouris
302 3564be49 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.set')
303 3564be49 Stavros Sachtouris
    def test_set_cloud(self, c_set):
304 3564be49 Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX
305 3564be49 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
306 3564be49 Stavros Sachtouris
307 3564be49 Stavros Sachtouris
        d = dict(k='v')
308 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=d) as get:
309 3564be49 Stavros Sachtouris
            _cnf.set_cloud('mycloud', 'opt', 'val')
310 3564be49 Stavros Sachtouris
            get.assert_called_once_with(CLOUD_PREFIX, 'mycloud')
311 3564be49 Stavros Sachtouris
            d['opt'] = 'val'
312 3564be49 Stavros Sachtouris
            self.assertEqual(
313 3564be49 Stavros Sachtouris
                c_set.mock_calls[-1], call(CLOUD_PREFIX, 'mycloud', d))
314 3564be49 Stavros Sachtouris
315 3564be49 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=None) as get:
316 3564be49 Stavros Sachtouris
            _cnf.set_cloud('mycloud', 'opt', 'val')
317 3564be49 Stavros Sachtouris
            get.assert_called_once_with(CLOUD_PREFIX, 'mycloud')
318 3564be49 Stavros Sachtouris
            d = dict(opt='val')
319 3564be49 Stavros Sachtouris
            self.assertEqual(
320 3564be49 Stavros Sachtouris
                c_set.mock_calls[-1], call(CLOUD_PREFIX, 'mycloud', d))
321 3564be49 Stavros Sachtouris
322 3564be49 Stavros Sachtouris
        with patch(
323 3564be49 Stavros Sachtouris
                'kamaki.cli.config.Config.get', side_effect=KeyError()) as get:
324 3564be49 Stavros Sachtouris
            _cnf.set_cloud('mycloud', 'opt', 'val')
325 3564be49 Stavros Sachtouris
            get.assert_called_once_with(CLOUD_PREFIX, 'mycloud')
326 3564be49 Stavros Sachtouris
            d = dict(opt='val')
327 3564be49 Stavros Sachtouris
            self.assertEqual(
328 3564be49 Stavros Sachtouris
                c_set.mock_calls[-1], call(CLOUD_PREFIX, 'mycloud', d))
329 3564be49 Stavros Sachtouris
330 2e616dbd Stavros Sachtouris
    def test__load_defaults(self):
331 2e616dbd Stavros Sachtouris
        from kamaki.cli.config import Config, DEFAULTS
332 2e616dbd Stavros Sachtouris
        _cnf = Config(path=self.f.name)
333 2e616dbd Stavros Sachtouris
334 2e616dbd Stavros Sachtouris
        with patch('kamaki.cli.config.Config.set') as c_set:
335 2e616dbd Stavros Sachtouris
            _cnf._load_defaults()
336 2e616dbd Stavros Sachtouris
            for i, (section, options) in enumerate(DEFAULTS.items()):
337 2e616dbd Stavros Sachtouris
                for j, (option, val) in enumerate(options.items()):
338 2e616dbd Stavros Sachtouris
                    self.assertEqual(
339 2e616dbd Stavros Sachtouris
                        c_set.mock_calls[(i + 1) * j],
340 2e616dbd Stavros Sachtouris
                        call(section, option, val))
341 2e616dbd Stavros Sachtouris
342 2e616dbd Stavros Sachtouris
    def test__get_dict(self):
343 2e616dbd Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX, DEFAULTS
344 2e616dbd Stavros Sachtouris
345 2e616dbd Stavros Sachtouris
        def make_file(lines):
346 2e616dbd Stavros Sachtouris
            f = NamedTemporaryFile()
347 2e616dbd Stavros Sachtouris
            f.writelines(lines)
348 2e616dbd Stavros Sachtouris
            f.flush()
349 2e616dbd Stavros Sachtouris
            return f
350 2e616dbd Stavros Sachtouris
351 2e616dbd Stavros Sachtouris
        with make_file([]) as f:
352 2e616dbd Stavros Sachtouris
            _cnf = Config(path=f.name)
353 2e616dbd Stavros Sachtouris
            for term in ('global', CLOUD_PREFIX):
354 2e616dbd Stavros Sachtouris
                self.assertEqual(DEFAULTS[term], _cnf._get_dict(term))
355 2e616dbd Stavros Sachtouris
            for term in ('nosection', ''):
356 2e616dbd Stavros Sachtouris
                self.assertEqual({}, _cnf._get_dict(term))
357 2e616dbd Stavros Sachtouris
358 2e616dbd Stavros Sachtouris
        with make_file(self.config_file_content) as f:
359 2e616dbd Stavros Sachtouris
            _cnf = Config(path=f.name)
360 2e616dbd Stavros Sachtouris
            for term in ('global', CLOUD_PREFIX):
361 2e616dbd Stavros Sachtouris
                self.assertNotEqual(DEFAULTS[term], _cnf._get_dict(term))
362 2e616dbd Stavros Sachtouris
363 2e616dbd Stavros Sachtouris
    def test_reload(self):
364 2e616dbd Stavros Sachtouris
        from kamaki.cli.config import Config
365 2e616dbd Stavros Sachtouris
        _cnf = Config(path=self.f.name)
366 2e616dbd Stavros Sachtouris
367 2e616dbd Stavros Sachtouris
        with patch('kamaki.cli.config.Config.__init__') as i:
368 2e616dbd Stavros Sachtouris
            _cnf.reload()
369 2e616dbd Stavros Sachtouris
            i.assert_called_once_with(self.f.name)
370 2e616dbd Stavros Sachtouris
371 8556d269 Stavros Sachtouris
    @patch('kamaki.cli.config.Config.get_cloud', return_value='get cloud')
372 8556d269 Stavros Sachtouris
    def test_get(self, get_cloud):
373 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
374 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
375 8556d269 Stavros Sachtouris
        self.assertEqual('pithos', _cnf.get('global', 'file_cli'))
376 8556d269 Stavros Sachtouris
        self.assertEqual(get_cloud.mock_calls, [])
377 8556d269 Stavros Sachtouris
        for opt, sec in (('cloud', 'non-existing'), ('non-opt', 'exists')):
378 8556d269 Stavros Sachtouris
            self.assertEqual(None, _cnf.get(opt, sec))
379 8556d269 Stavros Sachtouris
            self.assertEqual(get_cloud.mock_calls, [])
380 8556d269 Stavros Sachtouris
        self.assertEqual('get cloud', _cnf.get('cloud.demo', 'url'))
381 8556d269 Stavros Sachtouris
        self.assertEqual(get_cloud.mock_calls[-1], call('demo', 'url'))
382 8556d269 Stavros Sachtouris
383 8556d269 Stavros Sachtouris
    def test_set(self):
384 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX
385 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
386 8556d269 Stavros Sachtouris
387 8556d269 Stavros Sachtouris
        with patch(
388 8556d269 Stavros Sachtouris
                'kamaki.cli.config.Config._cloud_name',
389 8556d269 Stavros Sachtouris
                return_value='cn') as _cloud_name:
390 8556d269 Stavros Sachtouris
            with patch(
391 8556d269 Stavros Sachtouris
                    'kamaki.cli.config.Config.set_cloud',
392 8556d269 Stavros Sachtouris
                    return_value='sc') as set_cloud:
393 8556d269 Stavros Sachtouris
                self.assertEqual(
394 8556d269 Stavros Sachtouris
                    'sc', _cnf.set('%s.sec' % CLOUD_PREFIX, 'opt', 'val'))
395 8556d269 Stavros Sachtouris
                self.assertEqual(
396 8556d269 Stavros Sachtouris
                    _cloud_name.mock_calls[-1],
397 8556d269 Stavros Sachtouris
                    call('%s "sec"' % CLOUD_PREFIX))
398 8556d269 Stavros Sachtouris
                self.assertEqual(
399 8556d269 Stavros Sachtouris
                    set_cloud.mock_calls[-1], call('cn', 'opt', 'val'))
400 8556d269 Stavros Sachtouris
401 8556d269 Stavros Sachtouris
                self.assertTrue(len(_cnf.items('global')) > 0)
402 8556d269 Stavros Sachtouris
                self.assertEqual(None, _cnf.set('global', 'opt', 'val'))
403 8556d269 Stavros Sachtouris
                self.assertTrue(('opt', 'val') in _cnf.items('global'))
404 8556d269 Stavros Sachtouris
405 8556d269 Stavros Sachtouris
                self.assertTrue(len(_cnf.items('new')) == 0)
406 8556d269 Stavros Sachtouris
                self.assertEqual(None, _cnf.set('new', 'opt', 'val'))
407 8556d269 Stavros Sachtouris
                self.assertTrue(('opt', 'val') in _cnf.items('new'))
408 8556d269 Stavros Sachtouris
409 8556d269 Stavros Sachtouris
    def test_remove_option(self):
410 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
411 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
412 8556d269 Stavros Sachtouris
413 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('no-section')), 0)
414 8556d269 Stavros Sachtouris
        _cnf.remove_option('no-section', 'opt', False)
415 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('no-section')), 0)
416 8556d269 Stavros Sachtouris
        _cnf.remove_option('no-section', 'opt', True)
417 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('no-section')), 0)
418 8556d269 Stavros Sachtouris
419 8556d269 Stavros Sachtouris
        opt_num = len(_cnf.items('global'))
420 8556d269 Stavros Sachtouris
        self.assertTrue(opt_num > 0)
421 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'file_cli', False)
422 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('global')), opt_num)
423 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'file_cli', True)
424 8556d269 Stavros Sachtouris
        self.assertEqual(len(_cnf.items('global')), opt_num - 1)
425 8556d269 Stavros Sachtouris
426 8556d269 Stavros Sachtouris
        _cnf.set('global', 'server_cli', 'alt-server')
427 8556d269 Stavros Sachtouris
        self.assertTrue(('server_cli', 'alt-server') in _cnf.items('global'))
428 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'cyclades') in _cnf.items('global'))
429 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'server_cli', False)
430 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'alt-server') in _cnf.items('global'))
431 8556d269 Stavros Sachtouris
        self.assertTrue(('server_cli', 'cyclades') in _cnf.items('global'))
432 8556d269 Stavros Sachtouris
        _cnf.remove_option('global', 'server_cli', True)
433 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'alt-server') in _cnf.items('global'))
434 8556d269 Stavros Sachtouris
        self.assertFalse(('server_cli', 'cyclades') in _cnf.items('global'))
435 8556d269 Stavros Sachtouris
436 8556d269 Stavros Sachtouris
    def test_remove_from_cloud(self):
437 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config, CLOUD_PREFIX
438 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
439 8556d269 Stavros Sachtouris
440 8556d269 Stavros Sachtouris
        d = dict(k1='v1', k2='v2')
441 8556d269 Stavros Sachtouris
        with patch('kamaki.cli.config.Config.get', return_value=d) as get:
442 8556d269 Stavros Sachtouris
            _cnf.remove_from_cloud('cld', 'k1')
443 8556d269 Stavros Sachtouris
            self.assertEqual(d, dict(k2='v2'))
444 8556d269 Stavros Sachtouris
            self.assertRaises(KeyError, _cnf.remove_from_cloud, 'cld', 'opt')
445 8556d269 Stavros Sachtouris
            self.assertEqual(get.mock_calls, 2 * [call(CLOUD_PREFIX, 'cld')])
446 8556d269 Stavros Sachtouris
447 8556d269 Stavros Sachtouris
    @patch(
448 8556d269 Stavros Sachtouris
        'kamaki.cli.config.Config._get_dict',
449 8556d269 Stavros Sachtouris
        return_value={'k1': 'v1', 'k2': 'v2'})
450 8556d269 Stavros Sachtouris
    def test_keys(self, _get_dict):
451 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
452 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
453 8556d269 Stavros Sachtouris
454 8556d269 Stavros Sachtouris
        self.assertEqual(
455 8556d269 Stavros Sachtouris
            sorted(['k1', 'k2']), sorted(_cnf.keys('opt', 'boolean')))
456 8556d269 Stavros Sachtouris
        _get_dict.assert_called_once_with('opt', 'boolean')
457 8556d269 Stavros Sachtouris
458 8556d269 Stavros Sachtouris
    @patch(
459 8556d269 Stavros Sachtouris
        'kamaki.cli.config.Config._get_dict',
460 8556d269 Stavros Sachtouris
        return_value={'k1': 'v1', 'k2': 'v2'})
461 8556d269 Stavros Sachtouris
    def test_items(self, _get_dict):
462 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
463 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
464 8556d269 Stavros Sachtouris
465 8556d269 Stavros Sachtouris
        self.assertEqual(
466 8556d269 Stavros Sachtouris
            sorted([('k1', 'v1'), ('k2', 'v2')]),
467 8556d269 Stavros Sachtouris
            sorted(_cnf.items('opt', 'boolean')))
468 8556d269 Stavros Sachtouris
        _get_dict.assert_called_once_with('opt', 'boolean')
469 8556d269 Stavros Sachtouris
470 8556d269 Stavros Sachtouris
    def test_override(self):
471 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config
472 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
473 8556d269 Stavros Sachtouris
474 8556d269 Stavros Sachtouris
        _cnf.override('sec', 'opt', 'val')
475 8556d269 Stavros Sachtouris
        self.assertEqual(_cnf._overrides['sec']['opt'], 'val')
476 8556d269 Stavros Sachtouris
477 8556d269 Stavros Sachtouris
    def test_write(self):
478 8556d269 Stavros Sachtouris
        from kamaki.cli.config import Config, DEFAULTS
479 8556d269 Stavros Sachtouris
        _cnf = Config(path=self.f.name)
480 8556d269 Stavros Sachtouris
481 8556d269 Stavros Sachtouris
        exp = '%s[global]\n' % HEADER
482 8556d269 Stavros Sachtouris
        exp += ''.join([
483 8556d269 Stavros Sachtouris
            '%s = %s\n' % (k, v) for k, v in DEFAULTS['global'].items()])
484 8556d269 Stavros Sachtouris
        exp += '\n'
485 8556d269 Stavros Sachtouris
486 8556d269 Stavros Sachtouris
        _cnf.write()
487 8556d269 Stavros Sachtouris
        self.f.seek(0)
488 8556d269 Stavros Sachtouris
        self.assertEqual(self.f.read(), exp)
489 8556d269 Stavros Sachtouris
490 8556d269 Stavros Sachtouris
        del _cnf
491 8556d269 Stavros Sachtouris
        with NamedTemporaryFile() as f:
492 8556d269 Stavros Sachtouris
            f.write('\n'.join(self.config_file_content))
493 8556d269 Stavros Sachtouris
            f.flush()
494 8556d269 Stavros Sachtouris
            _cnf = Config(path=f.name)
495 8556d269 Stavros Sachtouris
            f.seek(0)
496 8556d269 Stavros Sachtouris
            self.assertEqual(f.read(), '\n'.join(self.config_file_content))
497 8556d269 Stavros Sachtouris
            _cnf.write()
498 8556d269 Stavros Sachtouris
            f.seek(0)
499 8556d269 Stavros Sachtouris
            file_contents = f.read()
500 8556d269 Stavros Sachtouris
            for line in self.config_file_content:
501 8556d269 Stavros Sachtouris
                self.assertTrue(line in file_contents)
502 8556d269 Stavros Sachtouris
            _cnf.set('sec', 'opt', 'val')
503 8556d269 Stavros Sachtouris
            _cnf.set('global', 'opt', 'val')
504 8556d269 Stavros Sachtouris
            _cnf.set('global', 'file_cli', 'val')
505 8556d269 Stavros Sachtouris
            _cnf.write()
506 8556d269 Stavros Sachtouris
            f.seek(0)
507 8556d269 Stavros Sachtouris
            file_contents = f.read()
508 8556d269 Stavros Sachtouris
            for line in ('file_cli = val\n', '[sec]\n', 'opt = val\n'):
509 8556d269 Stavros Sachtouris
                self.assertTrue(line in file_contents)
510 8556d269 Stavros Sachtouris
511 9f5cbafe Stavros Sachtouris
512 9f5cbafe Stavros Sachtouris
if __name__ == '__main__':
513 9f5cbafe Stavros Sachtouris
    from sys import argv
514 9f5cbafe Stavros Sachtouris
    from kamaki.cli.test import runTestCase
515 f767b407 Stavros Sachtouris
    runTestCase(Config, 'Config', argv[1:])