Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aws
GitHub Repository: aws/aws-cli
Path: blob/develop/tests/unit/customizations/test_commands.py
1567 views
1
# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License"). You
4
# may not use this file except in compliance with the License. A copy of
5
# the License is located at
6
#
7
# http://aws.amazon.com/apache2.0/
8
#
9
# or in the "license" file accompanying this file. This file is
10
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
# ANY KIND, either express or implied. See the License for the specific
12
# language governing permissions and limitations under the License.
13
from awscli.testutils import mock, unittest
14
15
from awscli.clidriver import CLIDriver
16
from awscli.customizations.commands import BasicHelp, BasicCommand
17
from awscli.customizations.commands import BasicDocHandler
18
from botocore.hooks import HierarchicalEmitter
19
from tests.unit.test_clidriver import FakeSession, FakeCommand
20
21
22
class MockCustomCommand(BasicCommand):
23
NAME = 'mock'
24
25
SUBCOMMANDS = [{'name': 'basic', 'command_class': BasicCommand}]
26
27
28
class TestCommandLoader(unittest.TestCase):
29
30
def test_basic_help_with_contents(self):
31
cmd_object = mock.Mock()
32
mock_module = mock.Mock()
33
mock_module.__file__ = '/some/root'
34
cmd_object.DESCRIPTION = BasicCommand.FROM_FILE(
35
'foo', 'bar', 'baz.txt', root_module=mock_module)
36
help_command = BasicHelp(mock.Mock(), cmd_object, {}, {})
37
with mock.patch('awscli.customizations.commands._open') as mock_open:
38
mock_open.return_value.__enter__.return_value.read.return_value = \
39
'fake description'
40
self.assertEqual(help_command.description, 'fake description')
41
42
43
class TestBasicCommand(unittest.TestCase):
44
45
def setUp(self):
46
self.session = mock.Mock()
47
self.command = BasicCommand(self.session)
48
49
def test_load_arg_table_property(self):
50
# Ensure ``_build_arg_table()`` is called if it has not been
51
# built via the ``arg_table`` property. It should be an empty
52
# dictionary.
53
orig_arg_table = self.command.arg_table
54
self.assertEqual(orig_arg_table, {})
55
# Ensure the ``arg_table`` is not built again if
56
# ``arg_table`` property is called again.
57
self.assertIs(orig_arg_table, self.command.arg_table)
58
59
def test_load_subcommand_table_property(self):
60
# Ensure ``_build_subcommand_table()`` is called if it has not
61
# been built via the ``subcommand_table`` property. It should be
62
# an empty dictionary.
63
orig_subcommand_table = self.command.subcommand_table
64
self.assertEqual(orig_subcommand_table, {})
65
# Ensure the ``subcommand_table`` is not built again if
66
# ``subcommand_table`` property is called again.
67
self.assertIs(orig_subcommand_table, self.command.subcommand_table)
68
69
def test_load_lineage(self):
70
self.assertEqual(self.command.lineage, [self.command])
71
self.assertEqual(self.command.lineage_names, [self.command.name])
72
73
def test_pass_lineage_to_child_command(self):
74
self.command = MockCustomCommand(self.session)
75
subcommand = self.command.subcommand_table['basic']
76
lineage = subcommand.lineage
77
self.assertEqual(len(lineage), 2)
78
self.assertEqual(lineage[0], self.command)
79
self.assertIsInstance(lineage[1], BasicCommand)
80
self.assertEqual(
81
subcommand.lineage_names,
82
[self.command.name, subcommand.name]
83
)
84
85
def test_event_class(self):
86
self.command = MockCustomCommand(self.session)
87
help_command = self.command.create_help_command()
88
self.assertEqual(help_command.event_class, 'mock')
89
subcommand = self.command.subcommand_table['basic']
90
sub_help_command = subcommand.create_help_command()
91
# Note that the name of this Subcommand was never changed even
92
# though it was put into the table as ``basic``. If no name
93
# is overridden it uses the name ``commandname``.
94
self.assertEqual(sub_help_command.event_class, 'mock.commandname')
95
96
97
class TestBasicCommandHooks(unittest.TestCase):
98
# These tests verify the proper hooks are emitted from BasicCommand.
99
100
def setUp(self):
101
self.session = FakeSession()
102
self.emitter = mock.Mock(wraps=HierarchicalEmitter())
103
self.session.emitter = self.emitter
104
105
def assert_events_fired_in_order(self, events):
106
args = self.emitter.emit.call_args_list
107
actual_events = [arg[0][0] for arg in args]
108
self.assertEqual(actual_events, events)
109
110
def inject_command(self, command_table, **kwargs):
111
command = FakeCommand(self.session)
112
command.NAME = 'foo'
113
command_table['foo'] = command
114
115
def test_expected_events_are_emitted_in_order(self):
116
driver = CLIDriver(session=self.session)
117
self.emitter.register(
118
'building-command-table.s3', self.inject_command)
119
120
driver.main('s3 foo'.split())
121
122
self.assert_events_fired_in_order([
123
'building-command-table.main',
124
'building-top-level-params',
125
'top-level-args-parsed',
126
'session-initialized',
127
'building-command-table.s3',
128
'building-command-table.foo',
129
'building-arg-table.foo',
130
'before-building-argument-table-parser.s3.foo'
131
])
132
133
134
class TestBasicDocHandler(unittest.TestCase):
135
def setUp(self):
136
self.session = mock.Mock()
137
self.obj = MockCustomCommand(self.session)
138
self.command_table = {}
139
self.arg_table = {}
140
141
def create_help_command(self):
142
return BasicHelp(
143
self.session, self.obj, self.command_table, self.arg_table
144
)
145
146
def create_arg_table(self):
147
return CLIDriver().create_help_command().arg_table
148
149
def generate_global_option_docs(self, help_command):
150
operation_handler = BasicDocHandler(help_command)
151
operation_handler.doc_global_option(help_command=help_command)
152
return help_command.doc.getvalue().decode('utf-8')
153
154
def generate_global_synopsis_docs(self, help_command):
155
operation_handler = BasicDocHandler(help_command)
156
operation_handler.doc_synopsis_end(help_command=help_command)
157
return help_command.doc.getvalue().decode('utf-8')
158
159
def assert_global_args_documented(self, arg_table, content):
160
for arg in arg_table:
161
self.assertIn(arg_table.get(arg).cli_name, content)
162
163
def assert_global_args_not_documented(self, arg_table, content):
164
for arg in arg_table:
165
self.assertNotIn(arg_table.get(arg).cli_name, content)
166
167
def test_includes_global_options_when_command_table_empty(self):
168
help_command = self.create_help_command()
169
arg_table = self.create_arg_table()
170
help_command.arg_table = arg_table
171
rendered = self.generate_global_option_docs(help_command)
172
self.assert_global_args_documented(arg_table, rendered)
173
174
def test_excludes_global_options_when_command_table_not_empty(self):
175
help_command = self.create_help_command()
176
arg_table = self.create_arg_table()
177
help_command.arg_table = arg_table
178
fake_command = FakeCommand(FakeSession())
179
fake_command.NAME = 'command'
180
help_command.command_table = {'command': fake_command}
181
rendered = self.generate_global_option_docs(help_command)
182
self.assert_global_args_not_documented(arg_table, rendered)
183
184
def test_includes_global_synopsis_when_command_table_empty(self):
185
help_command = self.create_help_command()
186
arg_table = self.create_arg_table()
187
help_command.arg_table = arg_table
188
rendered = self.generate_global_synopsis_docs(help_command)
189
self.assert_global_args_documented(arg_table, rendered)
190
191
def test_excludes_global_synopsis_when_command_table_not_empty(self):
192
help_command = self.create_help_command()
193
arg_table = self.create_arg_table()
194
help_command.arg_table = arg_table
195
fake_command = FakeCommand(FakeSession())
196
fake_command.NAME = 'command'
197
help_command.command_table = {'command': fake_command}
198
rendered = self.generate_global_synopsis_docs(help_command)
199
self.assert_global_args_not_documented(arg_table, rendered)
200
201