# -*- coding: utf-8 -*- import types from salt.cloud.clouds import azurearm as azure from tests.support.mixins import LoaderModuleMockMixin from tests.support.mock import MagicMock, create_autospec from tests.support.unit import TestCase, skipIf def copy_func(func, globals=None): # I do not know that this is complete, but it's sufficient for now. # The key to "moving" the function to another module (or stubbed module) # is to update __globals__. copied_func = types.FunctionType( func.__code__, globals, func.__name__, func.__defaults__, func.__closure__ ) copied_func.__module__ = func.__module__ copied_func.__doc__ = func.__doc__ copied_func.__kwdefaults__ = func.__kwdefaults__ copied_func.__dict__.update(func.__dict__) return copied_func def mock_module(mod, sut=None): if sut is None: sut = [None] mock = create_autospec(mod) # we need to provide a '__globals__' so functions being tested behave correctly. mock_globals = {} # exclude the system under test for name in sut: attr = getattr(mod, name) if isinstance(attr, types.FunctionType): attr = copy_func(attr, mock_globals) setattr(mock, name, attr) # fully populate our mock_globals for name in mod.__dict__: if name in mock.__dict__: mock_globals[name] = mock.__dict__[name] elif type(getattr(mod, name)) is type(types): # is a module mock_globals[name] = getattr(mock, name) else: mock_globals[name] = mod.__dict__[name] return mock class AzureTestCase(TestCase, LoaderModuleMockMixin): def setup_loader_modules(self): return {azure: {"__opts__": {}, "__active_provider_name__": None}} @skipIf(not azure.HAS_LIBS, "azure not available") def test_function_signatures(self): mock_azure = mock_module( azure, sut=["request_instance", "six", "__opts__", "__utils__"] ) mock_azure.create_network_interface.return_value = [ MagicMock(), MagicMock(), MagicMock(), ] mock_azure.salt.utils.stringutils.to_str.return_value = "P4ssw0rd" mock_azure.salt.utils.cloud.gen_keys.return_value = [MagicMock(), MagicMock()] mock_azure.__opts__["pki_dir"] = None mock_azure.request_instance.__globals__[ "__builtins__" ] = mock_azure.request_instance.__globals__["__builtins__"].copy() mock_azure.request_instance.__globals__["__builtins__"]["getattr"] = MagicMock() mock_azure.__utils__[ "cloud.fire_event" ] = mock_azure.salt.utils.cloud.fire_event mock_azure.__utils__[ "cloud.filter_event" ] = mock_azure.salt.utils.cloud.filter_event mock_azure.__opts__["sock_dir"] = MagicMock() mock_azure.__opts__["transport"] = MagicMock() mock_azure.request_instance( {"image": "http://img", "storage_account": "blah", "size": ""} ) # we literally only check that a final creation call occurred. mock_azure.get_conn.return_value.virtual_machines.create_or_update.assert_called_once() def test_get_configured_provider(self): mock_azure = mock_module( azure, sut=["get_configured_provider", "six", "__opts__", "__utils__"] ) good_combos = [ { "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617", "tenant": "ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF", "client_id": "ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF", "secret": "XXXXXXXXXXXXXXXXXXXXXXXX", }, { "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617", "username": "larry", "password": "123pass", }, {"subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617"}, ] for combo in good_combos: mock_azure.__opts__["providers"] = {"azure_test": {"azurearm": combo}} self.assertEqual(azure.get_configured_provider(), combo) bad_combos = [ {"subscrption": "3287abc8-f98a-c678-3bde-326766fd3617"}, {}, ] for combo in bad_combos: mock_azure.__opts__["providers"] = {"azure_test": {"azurearm": combo}} self.assertFalse(azure.get_configured_provider()) def test_get_conn(self): mock_azure = mock_module( azure, sut=["get_conn", "six", "__opts__", "__utils__"] ) mock_azure.__utils__["azurearm.get_client"] = lambda client_type, **kw: kw mock_azure.__opts__["providers"] = { "azure_test": { "azurearm": { "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617", "driver": "azurearm", "password": "monkeydonkey", } } } # password is stripped if username not provided expected = {"subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617"} self.assertEqual(azure.get_conn(client_type="compute"), expected) mock_azure.__opts__["providers"] = { "azure_test": { "azurearm": { "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617", "driver": "azurearm", "username": "donkeymonkey", "password": "monkeydonkey", } } } # username and password via provider config expected = { "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617", "username": "donkeymonkey", "password": "monkeydonkey", } self.assertEqual(azure.get_conn(client_type="compute"), expected)