1""" 2:maintainer: Alberto Planas <aplanas@suse.com> 3:platform: Linux 4""" 5 6 7import salt.modules.freezer as freezer 8from salt.exceptions import CommandExecutionError 9from tests.support.mixins import LoaderModuleMockMixin 10from tests.support.mock import MagicMock, patch 11from tests.support.unit import TestCase 12 13 14class FreezerTestCase(TestCase, LoaderModuleMockMixin): 15 """ 16 Test cases for salt.modules.freezer 17 """ 18 19 def setup_loader_modules(self): 20 return {freezer: {"__salt__": {}, "__opts__": {"cachedir": ""}}} 21 22 @patch("os.path.isfile") 23 def test_status(self, isfile): 24 """ 25 Test if a frozen state exist. 26 """ 27 isfile.side_effect = (True, True) 28 self.assertTrue(freezer.status()) 29 30 isfile.side_effect = (True, False) 31 self.assertFalse(freezer.status()) 32 33 @patch("os.listdir") 34 @patch("os.path.isdir") 35 def test_list(self, isdir, listdir): 36 """ 37 Test the listing of all frozen states. 38 """ 39 # There is no freezer directory 40 isdir.return_value = False 41 self.assertEqual(freezer.list_(), []) 42 43 # There is freezer directory, but is empty 44 isdir.return_value = True 45 listdir.return_value = [] 46 self.assertEqual(freezer.list_(), []) 47 48 # There is freezer directory with states 49 isdir.return_value = True 50 listdir.return_value = [ 51 "freezer-pkgs.yml", 52 "freezer-reps.yml", 53 "state-pkgs.yml", 54 "state-reps.yml", 55 "random-file", 56 ] 57 self.assertEqual(freezer.list_(), ["freezer", "state"]) 58 59 @patch("os.makedirs") 60 def test_freeze_fails_cache(self, makedirs): 61 """ 62 Test to freeze a current installation 63 """ 64 # Fails when creating the freeze cache directory 65 makedirs.side_effect = OSError() 66 self.assertRaises(CommandExecutionError, freezer.freeze) 67 68 @patch("salt.modules.freezer.status") 69 @patch("os.makedirs") 70 def test_freeze_fails_already_frozen(self, makedirs, status): 71 """ 72 Test to freeze a current installation 73 """ 74 # Fails when there is already a frozen state 75 status.return_value = True 76 self.assertRaises(CommandExecutionError, freezer.freeze) 77 makedirs.assert_called_once() 78 79 @patch("salt.utils.json.dump") 80 @patch("salt.modules.freezer.fopen") 81 @patch("salt.modules.freezer.status") 82 @patch("os.makedirs") 83 def test_freeze_success_two_freeze(self, makedirs, status, fopen, dump): 84 """ 85 Test to freeze a current installation 86 """ 87 # Freeze the current new state 88 status.return_value = False 89 salt_mock = { 90 "pkg.list_pkgs": MagicMock(return_value={}), 91 "pkg.list_repos": MagicMock(return_value={}), 92 } 93 with patch.dict(freezer.__salt__, salt_mock): 94 self.assertTrue(freezer.freeze("one")) 95 self.assertTrue(freezer.freeze("two")) 96 97 self.assertEqual(makedirs.call_count, 2) 98 self.assertEqual(salt_mock["pkg.list_pkgs"].call_count, 2) 99 self.assertEqual(salt_mock["pkg.list_repos"].call_count, 2) 100 fopen.assert_called() 101 dump.assert_called() 102 103 @patch("salt.utils.json.dump") 104 @patch("salt.modules.freezer.fopen") 105 @patch("salt.modules.freezer.status") 106 @patch("os.makedirs") 107 def test_freeze_success_new_state(self, makedirs, status, fopen, dump): 108 """ 109 Test to freeze a current installation 110 """ 111 # Freeze the current new state 112 status.return_value = False 113 salt_mock = { 114 "pkg.list_pkgs": MagicMock(return_value={}), 115 "pkg.list_repos": MagicMock(return_value={}), 116 } 117 with patch.dict(freezer.__salt__, salt_mock): 118 self.assertTrue(freezer.freeze()) 119 makedirs.assert_called_once() 120 salt_mock["pkg.list_pkgs"].assert_called_once() 121 salt_mock["pkg.list_repos"].assert_called_once() 122 fopen.assert_called() 123 dump.assert_called() 124 125 @patch("salt.utils.json.dump") 126 @patch("salt.modules.freezer.fopen") 127 @patch("salt.modules.freezer.status") 128 @patch("os.makedirs") 129 def test_freeze_success_force(self, makedirs, status, fopen, dump): 130 """ 131 Test to freeze a current installation 132 """ 133 # Freeze the current old state 134 status.return_value = True 135 salt_mock = { 136 "pkg.list_pkgs": MagicMock(return_value={}), 137 "pkg.list_repos": MagicMock(return_value={}), 138 } 139 with patch.dict(freezer.__salt__, salt_mock): 140 self.assertTrue(freezer.freeze(force=True)) 141 makedirs.assert_called_once() 142 salt_mock["pkg.list_pkgs"].assert_called_once() 143 salt_mock["pkg.list_repos"].assert_called_once() 144 fopen.assert_called() 145 dump.assert_called() 146 147 @patch("salt.modules.freezer.status") 148 def test_restore_fails_missing_state(self, status): 149 """ 150 Test to restore an old state 151 """ 152 # Fails if the state is not found 153 status.return_value = False 154 self.assertRaises(CommandExecutionError, freezer.restore) 155 156 @patch("salt.utils.json.load") 157 @patch("salt.modules.freezer.fopen") 158 @patch("salt.modules.freezer.status") 159 def test_restore_add_missing_repo(self, status, fopen, load): 160 """ 161 Test to restore an old state 162 """ 163 # Only a missing repo is installed 164 status.return_value = True 165 load.side_effect = ({}, {"missing-repo": {}}) 166 salt_mock = { 167 "pkg.list_pkgs": MagicMock(return_value={}), 168 "pkg.list_repos": MagicMock(return_value={}), 169 "pkg.mod_repo": MagicMock(), 170 } 171 with patch.dict(freezer.__salt__, salt_mock): 172 self.assertEqual( 173 freezer.restore(), 174 { 175 "pkgs": {"add": [], "remove": []}, 176 "repos": {"add": ["missing-repo"], "remove": []}, 177 "comment": [], 178 }, 179 ) 180 salt_mock["pkg.list_pkgs"].assert_called() 181 salt_mock["pkg.list_repos"].assert_called() 182 salt_mock["pkg.mod_repo"].assert_called_once() 183 fopen.assert_called() 184 load.assert_called() 185 186 @patch("salt.utils.json.load") 187 @patch("salt.modules.freezer.fopen") 188 @patch("salt.modules.freezer.status") 189 def test_restore_add_missing_package(self, status, fopen, load): 190 """ 191 Test to restore an old state 192 """ 193 # Only a missing package is installed 194 status.return_value = True 195 load.side_effect = ({"missing-package": {}}, {}) 196 salt_mock = { 197 "pkg.list_pkgs": MagicMock(return_value={}), 198 "pkg.list_repos": MagicMock(return_value={}), 199 "pkg.install": MagicMock(), 200 } 201 with patch.dict(freezer.__salt__, salt_mock): 202 self.assertEqual( 203 freezer.restore(), 204 { 205 "pkgs": {"add": ["missing-package"], "remove": []}, 206 "repos": {"add": [], "remove": []}, 207 "comment": [], 208 }, 209 ) 210 salt_mock["pkg.list_pkgs"].assert_called() 211 salt_mock["pkg.list_repos"].assert_called() 212 salt_mock["pkg.install"].assert_called_once() 213 fopen.assert_called() 214 load.assert_called() 215 216 @patch("salt.utils.json.load") 217 @patch("salt.modules.freezer.fopen") 218 @patch("salt.modules.freezer.status") 219 def test_restore_remove_extra_package(self, status, fopen, load): 220 """ 221 Test to restore an old state 222 """ 223 # Only an extra package is removed 224 status.return_value = True 225 load.side_effect = ({}, {}) 226 salt_mock = { 227 "pkg.list_pkgs": MagicMock(return_value={"extra-package": {}}), 228 "pkg.list_repos": MagicMock(return_value={}), 229 "pkg.remove": MagicMock(), 230 } 231 with patch.dict(freezer.__salt__, salt_mock): 232 self.assertEqual( 233 freezer.restore(), 234 { 235 "pkgs": {"add": [], "remove": ["extra-package"]}, 236 "repos": {"add": [], "remove": []}, 237 "comment": [], 238 }, 239 ) 240 salt_mock["pkg.list_pkgs"].assert_called() 241 salt_mock["pkg.list_repos"].assert_called() 242 salt_mock["pkg.remove"].assert_called_once() 243 fopen.assert_called() 244 load.assert_called() 245 246 @patch("salt.utils.json.load") 247 @patch("salt.modules.freezer.fopen") 248 @patch("salt.modules.freezer.status") 249 def test_restore_remove_extra_repo(self, status, fopen, load): 250 """ 251 Test to restore an old state 252 """ 253 # Only an extra repository is removed 254 status.return_value = True 255 load.side_effect = ({}, {}) 256 salt_mock = { 257 "pkg.list_pkgs": MagicMock(return_value={}), 258 "pkg.list_repos": MagicMock(return_value={"extra-repo": {}}), 259 "pkg.del_repo": MagicMock(), 260 } 261 with patch.dict(freezer.__salt__, salt_mock): 262 self.assertEqual( 263 freezer.restore(), 264 { 265 "pkgs": {"add": [], "remove": []}, 266 "repos": {"add": [], "remove": ["extra-repo"]}, 267 "comment": [], 268 }, 269 ) 270 salt_mock["pkg.list_pkgs"].assert_called() 271 salt_mock["pkg.list_repos"].assert_called() 272 salt_mock["pkg.del_repo"].assert_called_once() 273 fopen.assert_called() 274 load.assert_called() 275 276 @patch("os.remove") 277 @patch("salt.utils.json.load") 278 @patch("salt.modules.freezer.fopen") 279 @patch("salt.modules.freezer.status") 280 def test_restore_clean_yml(self, status, fopen, load, remove): 281 """ 282 Test to restore an old state 283 """ 284 status.return_value = True 285 salt_mock = { 286 "pkg.list_pkgs": MagicMock(return_value={}), 287 "pkg.list_repos": MagicMock(return_value={}), 288 "pkg.install": MagicMock(), 289 } 290 with patch.dict(freezer.__salt__, salt_mock): 291 self.assertEqual( 292 freezer.restore(clean=True), 293 { 294 "pkgs": {"add": [], "remove": []}, 295 "repos": {"add": [], "remove": []}, 296 "comment": [], 297 }, 298 ) 299 salt_mock["pkg.list_pkgs"].assert_called() 300 salt_mock["pkg.list_repos"].assert_called() 301 fopen.assert_called() 302 load.assert_called() 303 self.assertEqual(remove.call_count, 2) 304