1import os 2 3import salt.modules.file as file_ 4import salt.modules.heat as heat 5import salt.modules.win_file as win_file 6import salt.utils.platform 7import salt.utils.win_dacl as dacl 8from tests.support.mixins import LoaderModuleMockMixin 9from tests.support.mock import MagicMock, patch 10from tests.support.runtests import RUNTIME_VARS 11from tests.support.unit import TestCase 12 13 14class MockStacks: 15 """ 16 Mock stacks.StackManager 17 """ 18 19 def validate(self, **kwargs): 20 """ 21 Mock of stacks.StackManager.validate method 22 """ 23 self.mock_val_ret = MagicMock() 24 self.mock_val_ret.json.return_value = {"result": "mocked response"} 25 self.mock_validate = MagicMock() 26 self.mock_validate.post.return_value = self.mock_val_ret 27 return self.mock_validate 28 29 def create(self, **kwargs): 30 self.mock_create_ret = MagicMock() 31 self.mock_create_ret.json.return_value = { 32 "result": "mocked create", 33 "fields": kwargs, 34 } 35 self.mock_create = MagicMock() 36 self.mock_create.post.return_value = self.mock_create_ret 37 return self.mock_create 38 39 def update(self, name, **kwargs): 40 self.mock_update_ret = MagicMock() 41 self.mock_update_ret.json.return_value = { 42 "result": "mocked update", 43 "fields": kwargs, 44 "name": name, 45 } 46 self.mock_update = MagicMock() 47 self.mock_update.post.return_value = self.mock_update_ret 48 return self.mock_update 49 50 51class MockClient: 52 """ 53 Mock of Client class 54 """ 55 56 def __init__(self, profile=None, **conn_args): 57 self.stacks = MockStacks() 58 59 60class HeatTestCase(TestCase, LoaderModuleMockMixin): 61 """ 62 Test cases for salt.modules.heat 63 """ 64 65 def setup_loader_modules(self): 66 return { 67 heat: {"_auth": MockClient}, 68 file_: { 69 "__opts__": { 70 "hash_type": "sha256", 71 "cachedir": os.path.join(RUNTIME_VARS.TMP, "rootdir", "cache"), 72 "test": False, 73 }, 74 "__salt__": { 75 "config.option": MagicMock( 76 return_value={"obfuscate_templates": False} 77 ), 78 "config.backup_mode": MagicMock(return_value=False), 79 }, 80 }, 81 win_file: { 82 "__utils__": {"dacl.check_perms": salt.utils.win_dacl.check_perms} 83 }, 84 dacl: {"__opts__": {"test": False}}, 85 } 86 87 def setUp(self): 88 self.patch_check = patch("salt.modules.file.check_perms", file_.check_perms) 89 if salt.utils.platform.is_windows(): 90 self.patch_check = patch( 91 "salt.modules.file.check_perms", win_file.check_perms 92 ) 93 94 def test_heat_create_stack(self): 95 """ 96 Test salt.modules.heat.create_stack method 97 """ 98 patch_file = patch.dict( 99 heat.__salt__, 100 { 101 "file.get_managed": file_.get_managed, 102 "file.manage_file": file_.manage_file, 103 }, 104 ) 105 106 with patch_file, self.patch_check: 107 ret = heat.create_stack( 108 name="mystack", 109 profile="openstack1", 110 template_file=os.path.join( 111 RUNTIME_VARS.BASE_FILES, "templates", "heat-template.yml" 112 ), 113 ) 114 assert ret == {"result": True, "comment": "Created stack 'mystack'."} 115 116 def test_heat_create_stack_environment(self): 117 """ 118 Test salt.modules.heat.create_stack method with environment set 119 """ 120 patch_file = patch.dict( 121 "salt.modules.heat.__salt__", 122 { 123 "file.get_managed": file_.get_managed, 124 "file.manage_file": file_.manage_file, 125 }, 126 ) 127 with patch_file, self.patch_check: 128 ret = heat.create_stack( 129 name="mystack", 130 profile="openstack1", 131 environment=os.path.join( 132 RUNTIME_VARS.BASE_FILES, "templates", "heat-env.yml" 133 ), 134 template_file=os.path.join( 135 RUNTIME_VARS.BASE_FILES, "templates", "heat-template.yml" 136 ), 137 ) 138 assert ret == {"result": True, "comment": "Created stack 'mystack'."} 139 140 def test_heat_create_stack_environment_err(self): 141 """ 142 Test salt.modules.heat.create_stack method with environment set 143 and there is an error reading the environment file 144 """ 145 patch_file = patch.dict( 146 "salt.modules.heat.__salt__", 147 { 148 "file.get_managed": file_.get_managed, 149 "file.manage_file": MagicMock( 150 side_effect=[{"result": True}, {"result": False}] 151 ), 152 }, 153 ) 154 patch_template = patch( 155 "salt.modules.heat._parse_template", MagicMock(return_value=True) 156 ) 157 env_file = os.path.join(RUNTIME_VARS.BASE_FILES, "templates", "heat-env.yml") 158 with patch_file, patch_template, self.patch_check: 159 ret = heat.create_stack( 160 name="mystack", 161 profile="openstack1", 162 environment=env_file, 163 template_file=os.path.join( 164 RUNTIME_VARS.BASE_FILES, "templates", "heat-template.yml" 165 ), 166 ) 167 assert ret == { 168 "result": False, 169 "comment": "Can not open environment: {}, ".format(env_file), 170 } 171 172 def test_heat_update_stack(self): 173 """ 174 Test salt.modules.heat.update_method method 175 """ 176 patch_file = patch.dict( 177 heat.__salt__, 178 { 179 "file.get_managed": file_.get_managed, 180 "file.manage_file": file_.manage_file, 181 }, 182 ) 183 with patch_file, self.patch_check: 184 ret = heat.update_stack( 185 name="mystack", 186 profile="openstack1", 187 template_file=os.path.join( 188 RUNTIME_VARS.BASE_FILES, "templates", "heat-template.yml" 189 ), 190 ) 191 assert ret == {"result": True, "comment": ("Updated stack 'mystack'.",)} 192 193 def test_heat_update_stack_env(self): 194 """ 195 Test salt.modules.heat.update_method method 196 with environment set 197 """ 198 patch_file = patch.dict( 199 heat.__salt__, 200 { 201 "file.get_managed": file_.get_managed, 202 "file.manage_file": file_.manage_file, 203 }, 204 ) 205 with patch_file, self.patch_check: 206 ret = heat.update_stack( 207 name="mystack", 208 profile="openstack1", 209 template_file=os.path.join( 210 RUNTIME_VARS.BASE_FILES, "templates", "heat-template.yml" 211 ), 212 environment=os.path.join( 213 RUNTIME_VARS.BASE_FILES, "templates", "heat-env.yml" 214 ), 215 ) 216 assert ret == {"result": True, "comment": ("Updated stack 'mystack'.",)} 217 218 def test_heat_update_stack_env_err(self): 219 """ 220 Test salt.modules.heat.update_method method 221 with environment set and there is an error 222 reading the environment file 223 """ 224 patch_file = patch.dict( 225 heat.__salt__, 226 { 227 "file.get_managed": file_.get_managed, 228 "file.manage_file": MagicMock( 229 side_effect=[{"result": True}, {"result": False}] 230 ), 231 }, 232 ) 233 with patch_file, self.patch_check: 234 ret = heat.update_stack( 235 name="mystack", 236 profile="openstack1", 237 template_file=os.path.join( 238 RUNTIME_VARS.BASE_FILES, "templates", "heat-template.yml" 239 ), 240 environment=os.path.join( 241 RUNTIME_VARS.BASE_FILES, "templates", "heat-env.yml" 242 ), 243 ) 244 assert ret == { 245 "result": False, 246 "comment": "Error parsing template Template format version not found.", 247 } 248