~frankban/juju-quickstart/interactive-errors

« back to all changes in this revision

Viewing changes to quickstart/tests/cli/test_views.py

  • Committer: Francesco Banconi
  • Date: 2014-10-10 13:47:08 UTC
  • mfrom: (100.1.11 maas-detect)
  • Revision ID: francesco.banconi@canonical.com-20141010134708-4zu3585o1p9pmwtl
Support automatic detection of a logged in MAAS.

Automatically detect a logged in MAAS API, so that
it is possible to use the stored credentials to 
create and bootstrap a MAAS environment without
user intervention.

QA:
- ssh to the GUI MAAS;
- destroy the existing environment;
- remove the ~/.juju directory;
- use the MAAS UI (http://maas.jujugui.org/MAAS/nodes/)
  to release the nodes if they are not in a ready state;
- this branch is already checked out in ~/juju-quickstart/sandbox/;
- start quickstart from there:
  cd ~/juju-quickstart/sandbox/ && .venv/bin/python juju-quickstart
- quickstart should show the option to automatically create and
  bootstrap the MAAS environment;
- select the option and wait for the envirnment to be ready:
  this can fail due to juju/maas interaction problems we currently
  have, retrying the process should eventually succeed.

Done, thank you!

R=bac, jay.wren
CC=
https://codereview.appspot.com/157830043

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
from __future__ import unicode_literals
20
20
 
21
 
from contextlib import contextmanager
 
21
from contextlib import (
 
22
    contextmanager,
 
23
    nested,
 
24
)
22
25
import unittest
23
26
 
24
27
import mock
36
39
from quickstart.tests.cli import helpers as cli_helpers
37
40
 
38
41
 
 
42
MAAS_NAME = 'maas-name'
 
43
MAAS_SERVER = 'http://1.2.3.4/MAAS'
 
44
MAAS_API_KEY = 'maas-secret'
 
45
 
 
46
 
39
47
def local_envs_supported(value):
40
48
    """Simulate local environments support in the current platform.
41
49
 
48
56
        mock.Mock(return_value=value))
49
57
 
50
58
 
 
59
def maas_env_detected(value):
 
60
    """Simulate whether a logged in MAAS remote API has been detected.
 
61
 
 
62
    The value argument is a boolean representing whether or not a MAAS API
 
63
    is available. If available, also patch "maas list" to return the following
 
64
    default values: MAAS_NAME, MAAS_SERVER and MAAS_API_KEY.
 
65
    Return a context manager that can be used when calling views.
 
66
    """
 
67
    patch_cli_available = mock.patch(
 
68
        'quickstart.cli.views.maas.cli_available',
 
69
        mock.Mock(return_value=value))
 
70
    if value:
 
71
        return_value = (MAAS_NAME, MAAS_SERVER, MAAS_API_KEY)
 
72
        patch_get_api_info = mock.patch(
 
73
            'quickstart.cli.views.maas.get_api_info',
 
74
            mock.Mock(return_value=return_value))
 
75
        return nested(patch_cli_available, patch_get_api_info)
 
76
    return patch_cli_available
 
77
 
 
78
 
51
79
class TestShow(unittest.TestCase):
52
80
 
53
81
    @contextmanager
139
167
    base_status = ' \N{UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW} navigate '
140
168
    create_local_caption = (
141
169
        '\N{BULLET} automatically create and bootstrap a local environment')
 
170
    create_maas_caption = (
 
171
        '\N{BULLET} automatically create and bootstrap the {} MAAS '
 
172
        'environment'.format(MAAS_NAME))
142
173
 
143
174
    def test_view_default_return_value_on_exit(self):
144
175
        # The view configures the app so that the return value on user exit is
257
288
        # If that option is clicked, the view quits the application returning
258
289
        # the newly created env_data.
259
290
        env_db = envs.create_empty_env_db()
260
 
        with local_envs_supported(True):
261
 
            views.env_index(
262
 
                self.app, self.env_type_db, env_db, self.save_callable)
 
291
        with maas_env_detected(False):
 
292
            with local_envs_supported(True):
 
293
                views.env_index(
 
294
                    self.app, self.env_type_db, env_db, self.save_callable)
263
295
        buttons = self.get_widgets_in_contents(
264
296
            filter_function=self.is_a(ui.MenuButton))
265
297
        # The "create and bootstrap" button is the first one in the contents.
285
317
                self.app, self.env_type_db, env_db, self.save_callable)
286
318
        buttons = self.get_widgets_in_contents(
287
319
            filter_function=self.is_a(ui.MenuButton))
288
 
        # No "create and bootstrap" buttons are present.
 
320
        # No "create and bootstrap local" buttons are present.
289
321
        captions = map(cli_helpers.get_button_caption, buttons)
290
322
        self.assertNotIn(self.create_local_caption, captions)
291
323
 
 
324
    def test_create_and_bootstrap_maas_environment_clicked(self):
 
325
        # When there are no environments in the env_db and a remote MAAS API is
 
326
        # detected, the view exposes an option to automatically create and
 
327
        # bootstrap a new MAAS environment.
 
328
        # If that option is clicked, the view quits the application returning
 
329
        # the newly created env_data.
 
330
        env_db = envs.create_empty_env_db()
 
331
        with maas_env_detected(True):
 
332
            views.env_index(
 
333
                self.app, self.env_type_db, env_db, self.save_callable)
 
334
        buttons = self.get_widgets_in_contents(
 
335
            filter_function=self.is_a(ui.MenuButton))
 
336
        # The "create and bootstrap" button is the first one in the contents.
 
337
        create_button = buttons[0]
 
338
        self.assertEqual(
 
339
            self.create_maas_caption,
 
340
            cli_helpers.get_button_caption(create_button))
 
341
        # An AppExit is raised clicking the button.
 
342
        with self.assertRaises(ui.AppExit) as context_manager:
 
343
            cli_helpers.emit(create_button)
 
344
        new_env_db, env_data = context_manager.exception.return_value
 
345
        # The environments database is no longer empty.
 
346
        self.assertIn(MAAS_NAME, new_env_db['environments'])
 
347
        self.assertEqual(envs.get_env_data(new_env_db, MAAS_NAME), env_data)
 
348
 
 
349
    def test_create_and_bootstrap_maas_environment_missing(self):
 
350
        # The option to automatically create and bootstrap a new MAAS
 
351
        # environment is not displayed if no MAAS API endpoints are
 
352
        # available on the system
 
353
        env_db = envs.create_empty_env_db()
 
354
        with maas_env_detected(False):
 
355
            views.env_index(
 
356
                self.app, self.env_type_db, env_db, self.save_callable)
 
357
        buttons = self.get_widgets_in_contents(
 
358
            filter_function=self.is_a(ui.MenuButton))
 
359
        # No "create and bootstrap MAAS" buttons are present.
 
360
        captions = map(cli_helpers.get_button_caption, buttons)
 
361
        self.assertNotIn(self.create_maas_caption, captions)
 
362
 
292
363
    def test_selected_environment(self):
293
364
        # The default environment is already selected in the list.
294
365
        env_db = helpers.make_env_db(default='lxc')