File: core_tests.py

package info (click to toggle)
python-softlayer 6.2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 7,508 kB
  • sloc: python: 57,195; makefile: 133; xml: 97; sh: 59
file content (137 lines) | stat: -rw-r--r-- 4,941 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
"""
    SoftLayer.tests.CLI.core_tests
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    :license: MIT, see LICENSE for more details.
"""
import io
import logging

import click
from unittest import mock as mock

from requests.models import Response
import SoftLayer
from SoftLayer.CLI import core
from SoftLayer.CLI import environment
from SoftLayer import testing


class CoreTests(testing.TestCase):

    def test_load_all(self):
        for path, cmd in recursive_subcommand_loader(core.cli, current_path='root'):
            try:
                cmd.main(args=['--help'])
            except SystemExit as ex:
                if ex.code != 0:
                    self.fail("Non-zero exit code for command: %s" % path)

    def test_verbose_max(self):
        with mock.patch('logging.getLogger') as log_mock:
            result = self.run_command(['-vvv', 'vs', 'list'])

            self.assert_no_fail(result)
            log_mock().addHandler.assert_called_with(mock.ANY)
            log_mock().setLevel.assert_called_with(logging.DEBUG)

    def test_build_client(self):
        env = environment.Environment()
        result = self.run_command(['vs', 'list'], env=env)

        self.assert_no_fail(result)
        self.assertIsNotNone(env.client)

    def test_diagnostics(self):
        result = self.run_command(['-v', 'vs', 'list'])

        self.assert_no_fail(result)
        self.assertIn('SoftLayer_Account::getVirtualGuests', result.output)
        self.assertIn('"execution_time"', result.output)
        self.assertIn('"api_calls"', result.output)
        self.assertIn('"version"', result.output)
        self.assertIn('"python_version"', result.output)
        self.assertIn('"library_location"', result.output)

    @mock.patch('requests.get')
    def test_get_latest_version(self, request_get):
        response = Response()
        response.status_code = 200
        response.json = mock.MagicMock(return_value={"info": {"version": "1.1.1"}})
        request_get.return_value = response
        version = core.get_latest_version()
        self.assertIn('1.1.1', version)

    @mock.patch('requests.get')
    def test_unable_get_latest_version(self, request_get):
        request_get.side_effect = Exception
        version = core.get_latest_version()
        self.assertIn('Unable', version)

    @mock.patch('SoftLayer.CLI.core.get_latest_version')
    def test_get_version_message(self, get_latest_version_mock):
        get_latest_version_mock.return_value = '1.1.1'
        env = environment.Environment()
        result = self.run_command(['--version'], env=env)
        self.assert_no_fail(result)


class CoreMainTests(testing.TestCase):

    @mock.patch('SoftLayer.CLI.core.cli.main')
    @mock.patch('sys.stdout', new_callable=io.StringIO)
    def test_unexpected_error(self, stdoutmock, climock):
        climock.side_effect = AttributeError('Attribute foo does not exist')

        self.assertRaises(SystemExit, core.main)

        self.assertIn("Feel free to report this error as it is likely a bug",
                      stdoutmock.getvalue())
        self.assertIn("Traceback (most recent call last)",
                      stdoutmock.getvalue())
        self.assertIn("AttributeError: Attribute foo does not exist",
                      stdoutmock.getvalue())

    @mock.patch('SoftLayer.CLI.core.cli.main')
    @mock.patch('sys.stdout', new_callable=io.StringIO)
    def test_sl_error(self, stdoutmock, climock):
        ex = SoftLayer.SoftLayerAPIError('SoftLayer_Exception', 'Not found')
        climock.side_effect = ex

        self.assertRaises(SystemExit, core.main)

        self.assertIn("SoftLayerAPIError(SoftLayer_Exception): Not found",
                      stdoutmock.getvalue())

    @mock.patch('SoftLayer.CLI.core.cli.main')
    @mock.patch('sys.stdout', new_callable=io.StringIO)
    def test_auth_error(self, stdoutmock, climock):
        ex = SoftLayer.SoftLayerAPIError('SoftLayer_Exception',
                                         'Invalid API token.')
        climock.side_effect = ex

        self.assertRaises(SystemExit, core.main)

        self.assertIn("Authentication Failed:", stdoutmock.getvalue())
        self.assertIn("use 'slcli config setup'", stdoutmock.getvalue())


def recursive_subcommand_loader(root, current_path=''):
    """Recursively load and list every command."""

    if getattr(root, 'list_commands', None) is None:
        return

    ctx = click.Context(root)

    for command in root.list_commands(ctx):
        new_path = '%s:%s' % (current_path, command)
        logging.info("loading %s", new_path)
        new_root = root.get_command(ctx, command)
        if new_root is None:
            raise Exception('Could not load command: %s' % command)

        for path, cmd in recursive_subcommand_loader(new_root,
                                                     current_path=new_path):
            yield path, cmd
        yield current_path, new_root