def test_command_index_positional_argument(self): from azure.cli.core._session import INDEX from azure.cli.core import CommandIndex cli = DummyCli() loader = cli.commands_loader index = CommandIndex() index.invalidate() # Test command index is built for command with positional argument cmd_tbl = loader.load_command_table( ["extra", "extra", "positional_argument"]) self.assertDictEqual(INDEX[CommandIndex._COMMAND_INDEX], self.expected_command_index) self.assertEqual(list(cmd_tbl), [ 'hello mod-only', 'hello overridden', 'extra final', 'hello ext-only' ]) # Test command index is used by command with positional argument cmd_tbl = loader.load_command_table( ["hello", "mod-only", "positional_argument"]) self.assertDictEqual(INDEX[CommandIndex._COMMAND_INDEX], self.expected_command_index) self.assertEqual( list(cmd_tbl), ['hello mod-only', 'hello overridden', 'hello ext-only']) # Test command index is used by command with positional argument cmd_tbl = loader.load_command_table( ["extra", "final", "positional_argument2"]) self.assertDictEqual(INDEX[CommandIndex._COMMAND_INDEX], self.expected_command_index) self.assertEqual(list(cmd_tbl), ['extra final'])
def test_command_index_always_loaded_extensions(self): cli = DummyCli() loader = cli.commands_loader from azure.cli.core import CommandIndex index = CommandIndex() index.invalidate() # Test azext_always_loaded is loaded when command index is rebuilt with mock.patch('azure.cli.core.ALWAYS_LOADED_EXTENSIONS', ['azext_always_loaded']): loader.load_command_table(["hello", "mod-only"]) self.assertEqual(TestCommandRegistration.test_hook, "FAKE_HANDLER") TestCommandRegistration.test_hook = [] # Test azext_always_loaded is loaded when command index is used with mock.patch('azure.cli.core.ALWAYS_LOADED_EXTENSIONS', ['azext_always_loaded']): loader.load_command_table(["hello", "mod-only"]) self.assertEqual(TestCommandRegistration.test_hook, "FAKE_HANDLER")
def test_command_index(self): from azure.cli.core._session import INDEX from azure.cli.core import CommandIndex, __version__ cli = DummyCli() loader = cli.commands_loader command_index = CommandIndex(cli) expected_command_index = { 'hello': [ 'azure.cli.command_modules.hello', 'azext_hello2', 'azext_hello1' ], 'extra': ['azure.cli.command_modules.extra'] } expected_command_table = [ 'hello mod-only', 'hello overridden', 'extra unused', 'hello ext-only' ] def _set_index(dict_): INDEX[CommandIndex._COMMAND_INDEX] = dict_ def _check_index(): self.assertEqual(INDEX[CommandIndex._COMMAND_INDEX_VERSION], __version__) self.assertEqual(INDEX[CommandIndex._COMMAND_INDEX_CLOUD_PROFILE], cli.cloud.profile) self.assertDictEqual(INDEX[CommandIndex._COMMAND_INDEX], expected_command_index) # Clear the command index _set_index({}) self.assertFalse(INDEX[CommandIndex._COMMAND_INDEX]) loader.load_command_table(None) # Test command index is built for None args _check_index() # Test command index is built when `args` is provided _set_index({}) loader.load_command_table(["hello", "mod-only"]) _check_index() # Test rebuild command index if no module found _set_index({"network": ["azure.cli.command_modules.network"]}) loader.load_command_table(["hello", "mod-only"]) _check_index() with mock.patch("azure.cli.core.__version__", "2.7.0"), mock.patch.object(cli.cloud, "profile", "2019-03-01-hybrid"): def update_and_check_index(): loader.load_command_table(["hello", "mod-only"]) self.assertEqual(INDEX[CommandIndex._COMMAND_INDEX_VERSION], "2.7.0") self.assertEqual( INDEX[CommandIndex._COMMAND_INDEX_CLOUD_PROFILE], "2019-03-01-hybrid") self.assertDictEqual(INDEX[CommandIndex._COMMAND_INDEX], expected_command_index) # Test rebuild command index if version is not present del INDEX[CommandIndex._COMMAND_INDEX_VERSION] del INDEX[CommandIndex._COMMAND_INDEX] update_and_check_index() # Test rebuild command index if version is not valid INDEX[CommandIndex._COMMAND_INDEX_VERSION] = "" _set_index({}) update_and_check_index() # Test rebuild command index if version is outdated INDEX[CommandIndex._COMMAND_INDEX_VERSION] = "2.6.0" _set_index({}) update_and_check_index() # Test rebuild command index if profile is outdated INDEX[CommandIndex. _COMMAND_INDEX_CLOUD_PROFILE] = "2017-03-09-profile" _set_index({}) update_and_check_index() # Test rebuild command index if modules are found but outdated # This only happens in dev environment. For users, the version check logic prevents it _set_index({"hello": ["azure.cli.command_modules.extra"]}) loader.load_command_table(["hello", "mod-only"]) _check_index() # Test irrelevant commands are not loaded _set_index(expected_command_index) cmd_tbl = loader.load_command_table(["hello", "mod-only"]) self.assertEqual( ['hello mod-only', 'hello overridden', 'hello ext-only'], list(cmd_tbl.keys())) # Full scenario test 1: Installing an extension 'azext_hello1' that extends 'hello' group outdated_command_index = { 'hello': ['azure.cli.command_modules.hello'], 'extra': ['azure.cli.command_modules.extra'] } _set_index(outdated_command_index) # Command for an outdated group cmd_tbl = loader.load_command_table(["hello", "-h"]) # Index is not updated, and only built-in commands are loaded _set_index(outdated_command_index) self.assertListEqual(list(cmd_tbl), ['hello mod-only', 'hello overridden']) # Command index is explicitly invalidated by azure.cli.core.extension.operations.add_extension command_index.invalidate() cmd_tbl = loader.load_command_table(["hello", "-h"]) # Index is updated, and new commands are loaded _check_index() self.assertListEqual(list(cmd_tbl), expected_command_table) # Full scenario test 2: Installing extension 'azext_hello2' that overrides existing command 'hello overridden' outdated_command_index = { 'hello': ['azure.cli.command_modules.hello', 'azext_hello1'], 'extra': ['azure.cli.command_modules.extra'] } _set_index(outdated_command_index) # Command for an overridden command cmd_tbl = loader.load_command_table(["hello", "overridden"]) # Index is not updated self.assertEqual(INDEX[CommandIndex._COMMAND_INDEX], outdated_command_index) # With the old command index, 'hello overridden' is loaded from the build-in module hello_overridden_cmd = cmd_tbl['hello overridden'] self.assertEqual(hello_overridden_cmd.command_source, 'hello') self.assertListEqual( list(cmd_tbl), ['hello mod-only', 'hello overridden', 'hello ext-only']) # Command index is explicitly invalidated by azure.cli.core.extension.operations.add_extension command_index.invalidate() # Command index is updated, and 'hello overridden' is loaded from the new extension cmd_tbl = loader.load_command_table(["hello", "overridden"]) hello_overridden_cmd = cmd_tbl['hello overridden'] self.assertTrue( isinstance(hello_overridden_cmd.command_source, ExtensionCommandSource)) _check_index() self.assertListEqual(list(cmd_tbl), expected_command_table) # Call again with the new command index. Irrelevant commands are not loaded cmd_tbl = loader.load_command_table(["hello", "overridden"]) hello_overridden_cmd = cmd_tbl['hello overridden'] self.assertTrue( isinstance(hello_overridden_cmd.command_source, ExtensionCommandSource)) _check_index() self.assertListEqual( list(cmd_tbl), ['hello mod-only', 'hello overridden', 'hello ext-only']) del INDEX[CommandIndex._COMMAND_INDEX_VERSION] del INDEX[CommandIndex._COMMAND_INDEX_CLOUD_PROFILE] del INDEX[CommandIndex._COMMAND_INDEX]