1import types 2 3import pytest 4from salt.cloud.clouds import azurearm as azure 5from tests.support.mock import MagicMock, create_autospec, patch 6 7 8def copy_func(func, globals=None): 9 # I do not know that this is complete, but it's sufficient for now. 10 # The key to "moving" the function to another module (or stubbed module) 11 # is to update __globals__. 12 13 copied_func = types.FunctionType( 14 func.__code__, globals, func.__name__, func.__defaults__, func.__closure__ 15 ) 16 copied_func.__module__ = func.__module__ 17 copied_func.__doc__ = func.__doc__ 18 copied_func.__kwdefaults__ = func.__kwdefaults__ 19 copied_func.__dict__.update(func.__dict__) 20 return copied_func 21 22 23def mock_module(mod, sut=None): 24 if sut is None: 25 sut = [None] 26 27 mock = create_autospec(mod) 28 29 # we need to provide a '__globals__' so functions being tested behave correctly. 30 mock_globals = {} 31 32 # exclude the system under test 33 for name in sut: 34 attr = getattr(mod, name) 35 if isinstance(attr, types.FunctionType): 36 attr = copy_func(attr, mock_globals) 37 setattr(mock, name, attr) 38 39 # fully populate our mock_globals 40 for name in mod.__dict__: 41 if name in mock.__dict__: 42 mock_globals[name] = mock.__dict__[name] 43 elif type(getattr(mod, name)) is type(types): # is a module 44 mock_globals[name] = getattr(mock, name) 45 else: 46 mock_globals[name] = mod.__dict__[name] 47 48 return mock 49 50 51@pytest.fixture 52def configure_loader_modules(): 53 return {azure: {"__opts__": {}, "__active_provider_name__": None}} 54 55 56@pytest.mark.skipif(not azure.HAS_LIBS, reason="azure not available") 57def test_function_signatures(): 58 mock_azure = mock_module(azure, sut=["request_instance", "__opts__", "__utils__"]) 59 mock_azure.create_network_interface.return_value = [ 60 MagicMock(), 61 MagicMock(), 62 MagicMock(), 63 ] 64 mock_azure.salt.utils.stringutils.to_str.return_value = "P4ssw0rd" 65 mock_azure.salt.utils.cloud.gen_keys.return_value = [MagicMock(), MagicMock()] 66 mock_azure.__opts__["pki_dir"] = None 67 68 mock_azure.request_instance.__globals__[ 69 "__builtins__" 70 ] = mock_azure.request_instance.__globals__["__builtins__"].copy() 71 mock_azure.request_instance.__globals__["__builtins__"]["getattr"] = MagicMock() 72 73 mock_azure.__utils__["cloud.fire_event"] = mock_azure.salt.utils.cloud.fire_event 74 mock_azure.__utils__[ 75 "cloud.filter_event" 76 ] = mock_azure.salt.utils.cloud.filter_event 77 mock_azure.__opts__["sock_dir"] = MagicMock() 78 mock_azure.__opts__["transport"] = MagicMock() 79 80 mock_azure.request_instance( 81 {"image": "http://img", "storage_account": "blah", "size": ""} 82 ) 83 84 # we literally only check that a final creation call occurred. 85 mock_azure.get_conn.return_value.virtual_machines.create_or_update.assert_called_once() 86 87 88def test_get_configured_provider(): 89 mock_azure = mock_module( 90 azure, sut=["get_configured_provider", "__opts__", "__utils__"] 91 ) 92 93 good_combos = [ 94 { 95 "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617", 96 "tenant": "ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF", 97 "client_id": "ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF", 98 "secret": "XXXXXXXXXXXXXXXXXXXXXXXX", 99 }, 100 { 101 "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617", 102 "username": "larry", 103 "password": "123pass", 104 }, 105 {"subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617"}, 106 ] 107 108 for combo in good_combos: 109 mock_azure.__opts__["providers"] = {"azure_test": {"azurearm": combo}} 110 assert azure.get_configured_provider() == combo 111 112 bad_combos = [ 113 {"subscrption": "3287abc8-f98a-c678-3bde-326766fd3617"}, 114 {}, 115 ] 116 117 for combo in bad_combos: 118 mock_azure.__opts__["providers"] = {"azure_test": {"azurearm": combo}} 119 assert not azure.get_configured_provider() 120 121 122def test_get_conn(): 123 mock_azure = mock_module(azure, sut=["get_conn", "__opts__", "__utils__"]) 124 125 mock_azure.__opts__["providers"] = { 126 "azure_test": { 127 "azurearm": { 128 "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617", 129 "driver": "azurearm", 130 "password": "monkeydonkey", 131 } 132 } 133 } 134 # password is stripped if username not provided 135 expected = {"subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617"} 136 with patch( 137 "salt.utils.azurearm.get_client", side_effect=lambda client_type, **kw: kw 138 ): 139 assert azure.get_conn(client_type="compute") == expected 140 141 mock_azure.__opts__["providers"] = { 142 "azure_test": { 143 "azurearm": { 144 "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617", 145 "driver": "azurearm", 146 "username": "donkeymonkey", 147 "password": "monkeydonkey", 148 } 149 } 150 } 151 # username and password via provider config 152 expected = { 153 "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617", 154 "username": "donkeymonkey", 155 "password": "monkeydonkey", 156 } 157 with patch( 158 "salt.utils.azurearm.get_client", side_effect=lambda client_type, **kw: kw 159 ): 160 assert azure.get_conn(client_type="compute") == expected 161