Path: blob/develop/tests/unit/customizations/test_commands.py
1567 views
# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.1#2# Licensed under the Apache License, Version 2.0 (the "License"). You3# may not use this file except in compliance with the License. A copy of4# the License is located at5#6# http://aws.amazon.com/apache2.0/7#8# or in the "license" file accompanying this file. This file is9# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF10# ANY KIND, either express or implied. See the License for the specific11# language governing permissions and limitations under the License.12from awscli.testutils import mock, unittest1314from awscli.clidriver import CLIDriver15from awscli.customizations.commands import BasicHelp, BasicCommand16from awscli.customizations.commands import BasicDocHandler17from botocore.hooks import HierarchicalEmitter18from tests.unit.test_clidriver import FakeSession, FakeCommand192021class MockCustomCommand(BasicCommand):22NAME = 'mock'2324SUBCOMMANDS = [{'name': 'basic', 'command_class': BasicCommand}]252627class TestCommandLoader(unittest.TestCase):2829def test_basic_help_with_contents(self):30cmd_object = mock.Mock()31mock_module = mock.Mock()32mock_module.__file__ = '/some/root'33cmd_object.DESCRIPTION = BasicCommand.FROM_FILE(34'foo', 'bar', 'baz.txt', root_module=mock_module)35help_command = BasicHelp(mock.Mock(), cmd_object, {}, {})36with mock.patch('awscli.customizations.commands._open') as mock_open:37mock_open.return_value.__enter__.return_value.read.return_value = \38'fake description'39self.assertEqual(help_command.description, 'fake description')404142class TestBasicCommand(unittest.TestCase):4344def setUp(self):45self.session = mock.Mock()46self.command = BasicCommand(self.session)4748def test_load_arg_table_property(self):49# Ensure ``_build_arg_table()`` is called if it has not been50# built via the ``arg_table`` property. It should be an empty51# dictionary.52orig_arg_table = self.command.arg_table53self.assertEqual(orig_arg_table, {})54# Ensure the ``arg_table`` is not built again if55# ``arg_table`` property is called again.56self.assertIs(orig_arg_table, self.command.arg_table)5758def test_load_subcommand_table_property(self):59# Ensure ``_build_subcommand_table()`` is called if it has not60# been built via the ``subcommand_table`` property. It should be61# an empty dictionary.62orig_subcommand_table = self.command.subcommand_table63self.assertEqual(orig_subcommand_table, {})64# Ensure the ``subcommand_table`` is not built again if65# ``subcommand_table`` property is called again.66self.assertIs(orig_subcommand_table, self.command.subcommand_table)6768def test_load_lineage(self):69self.assertEqual(self.command.lineage, [self.command])70self.assertEqual(self.command.lineage_names, [self.command.name])7172def test_pass_lineage_to_child_command(self):73self.command = MockCustomCommand(self.session)74subcommand = self.command.subcommand_table['basic']75lineage = subcommand.lineage76self.assertEqual(len(lineage), 2)77self.assertEqual(lineage[0], self.command)78self.assertIsInstance(lineage[1], BasicCommand)79self.assertEqual(80subcommand.lineage_names,81[self.command.name, subcommand.name]82)8384def test_event_class(self):85self.command = MockCustomCommand(self.session)86help_command = self.command.create_help_command()87self.assertEqual(help_command.event_class, 'mock')88subcommand = self.command.subcommand_table['basic']89sub_help_command = subcommand.create_help_command()90# Note that the name of this Subcommand was never changed even91# though it was put into the table as ``basic``. If no name92# is overridden it uses the name ``commandname``.93self.assertEqual(sub_help_command.event_class, 'mock.commandname')949596class TestBasicCommandHooks(unittest.TestCase):97# These tests verify the proper hooks are emitted from BasicCommand.9899def setUp(self):100self.session = FakeSession()101self.emitter = mock.Mock(wraps=HierarchicalEmitter())102self.session.emitter = self.emitter103104def assert_events_fired_in_order(self, events):105args = self.emitter.emit.call_args_list106actual_events = [arg[0][0] for arg in args]107self.assertEqual(actual_events, events)108109def inject_command(self, command_table, **kwargs):110command = FakeCommand(self.session)111command.NAME = 'foo'112command_table['foo'] = command113114def test_expected_events_are_emitted_in_order(self):115driver = CLIDriver(session=self.session)116self.emitter.register(117'building-command-table.s3', self.inject_command)118119driver.main('s3 foo'.split())120121self.assert_events_fired_in_order([122'building-command-table.main',123'building-top-level-params',124'top-level-args-parsed',125'session-initialized',126'building-command-table.s3',127'building-command-table.foo',128'building-arg-table.foo',129'before-building-argument-table-parser.s3.foo'130])131132133class TestBasicDocHandler(unittest.TestCase):134def setUp(self):135self.session = mock.Mock()136self.obj = MockCustomCommand(self.session)137self.command_table = {}138self.arg_table = {}139140def create_help_command(self):141return BasicHelp(142self.session, self.obj, self.command_table, self.arg_table143)144145def create_arg_table(self):146return CLIDriver().create_help_command().arg_table147148def generate_global_option_docs(self, help_command):149operation_handler = BasicDocHandler(help_command)150operation_handler.doc_global_option(help_command=help_command)151return help_command.doc.getvalue().decode('utf-8')152153def generate_global_synopsis_docs(self, help_command):154operation_handler = BasicDocHandler(help_command)155operation_handler.doc_synopsis_end(help_command=help_command)156return help_command.doc.getvalue().decode('utf-8')157158def assert_global_args_documented(self, arg_table, content):159for arg in arg_table:160self.assertIn(arg_table.get(arg).cli_name, content)161162def assert_global_args_not_documented(self, arg_table, content):163for arg in arg_table:164self.assertNotIn(arg_table.get(arg).cli_name, content)165166def test_includes_global_options_when_command_table_empty(self):167help_command = self.create_help_command()168arg_table = self.create_arg_table()169help_command.arg_table = arg_table170rendered = self.generate_global_option_docs(help_command)171self.assert_global_args_documented(arg_table, rendered)172173def test_excludes_global_options_when_command_table_not_empty(self):174help_command = self.create_help_command()175arg_table = self.create_arg_table()176help_command.arg_table = arg_table177fake_command = FakeCommand(FakeSession())178fake_command.NAME = 'command'179help_command.command_table = {'command': fake_command}180rendered = self.generate_global_option_docs(help_command)181self.assert_global_args_not_documented(arg_table, rendered)182183def test_includes_global_synopsis_when_command_table_empty(self):184help_command = self.create_help_command()185arg_table = self.create_arg_table()186help_command.arg_table = arg_table187rendered = self.generate_global_synopsis_docs(help_command)188self.assert_global_args_documented(arg_table, rendered)189190def test_excludes_global_synopsis_when_command_table_not_empty(self):191help_command = self.create_help_command()192arg_table = self.create_arg_table()193help_command.arg_table = arg_table194fake_command = FakeCommand(FakeSession())195fake_command.NAME = 'command'196help_command.command_table = {'command': fake_command}197rendered = self.generate_global_synopsis_docs(help_command)198self.assert_global_args_not_documented(arg_table, rendered)199200201