test_win_dism.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. # -*- coding: utf-8 -*-
  2. # Import Python libs
  3. from __future__ import absolute_import, print_function, unicode_literals
  4. # Import Salt Libs
  5. import salt.states.win_dism as dism
  6. # Import Salt Testing Libs
  7. from tests.support.mixins import LoaderModuleMockMixin
  8. from tests.support.mock import MagicMock, patch
  9. from tests.support.unit import TestCase
  10. class WinDismTestCase(TestCase, LoaderModuleMockMixin):
  11. def setup_loader_modules(self):
  12. return {dism: {}}
  13. def test_capability_installed(self):
  14. """
  15. Test capability installed state
  16. """
  17. expected = {
  18. "comment": "Installed Capa2",
  19. "changes": {"capability": {"new": ["Capa2"]}, "retcode": 0},
  20. "name": "Capa2",
  21. "result": True,
  22. }
  23. mock_installed = MagicMock(side_effect=[["Capa1"], ["Capa1", "Capa2"]])
  24. mock_add = MagicMock(return_value={"retcode": 0})
  25. with patch.dict(
  26. dism.__salt__,
  27. {
  28. "dism.installed_capabilities": mock_installed,
  29. "dism.add_capability": mock_add,
  30. },
  31. ):
  32. with patch.dict(dism.__opts__, {"test": False}):
  33. out = dism.capability_installed("Capa2", "somewhere", True)
  34. mock_installed.assert_called_with()
  35. mock_add.assert_called_once_with(
  36. "Capa2", "somewhere", True, None, False
  37. )
  38. self.assertEqual(out, expected)
  39. def test_capability_installed_failure(self):
  40. """
  41. Test installing a capability which fails with DISM
  42. """
  43. expected = {
  44. "comment": "Failed to install Capa2: Failed",
  45. "changes": {},
  46. "name": "Capa2",
  47. "result": False,
  48. }
  49. mock_installed = MagicMock(side_effect=[["Capa1"], ["Capa1"]])
  50. mock_add = MagicMock(return_value={"retcode": 67, "stdout": "Failed"})
  51. with patch.dict(
  52. dism.__salt__,
  53. {
  54. "dism.installed_capabilities": mock_installed,
  55. "dism.add_capability": mock_add,
  56. },
  57. ):
  58. with patch.dict(dism.__opts__, {"test": False}):
  59. out = dism.capability_installed("Capa2", "somewhere", True)
  60. mock_installed.assert_called_with()
  61. mock_add.assert_called_once_with(
  62. "Capa2", "somewhere", True, None, False
  63. )
  64. self.assertEqual(out, expected)
  65. def test_capability_installed_installed(self):
  66. """
  67. Test installing a capability already installed
  68. """
  69. expected = {
  70. "comment": "The capability Capa2 is already installed",
  71. "changes": {},
  72. "name": "Capa2",
  73. "result": True,
  74. }
  75. mock_installed = MagicMock(return_value=["Capa1", "Capa2"])
  76. mock_add = MagicMock()
  77. with patch.dict(
  78. dism.__salt__,
  79. {
  80. "dism.installed_capabilities": mock_installed,
  81. "dism.add_capability": mock_add,
  82. },
  83. ):
  84. with patch.dict(dism.__opts__, {"test": False}):
  85. out = dism.capability_installed("Capa2", "somewhere", True)
  86. mock_installed.assert_called_once_with()
  87. assert not mock_add.called
  88. self.assertEqual(out, expected)
  89. def test_capability_removed(self):
  90. """
  91. Test capability removed state
  92. """
  93. expected = {
  94. "comment": "Removed Capa2",
  95. "changes": {"capability": {"old": ["Capa2"]}, "retcode": 0},
  96. "name": "Capa2",
  97. "result": True,
  98. }
  99. mock_removed = MagicMock(side_effect=[["Capa1", "Capa2"], ["Capa1"]])
  100. mock_remove = MagicMock(return_value={"retcode": 0})
  101. with patch.dict(
  102. dism.__salt__,
  103. {
  104. "dism.installed_capabilities": mock_removed,
  105. "dism.remove_capability": mock_remove,
  106. },
  107. ):
  108. with patch.dict(dism.__opts__, {"test": False}):
  109. out = dism.capability_removed("Capa2")
  110. mock_removed.assert_called_with()
  111. mock_remove.assert_called_once_with("Capa2", None, False)
  112. self.assertEqual(out, expected)
  113. def test_capability_removed_failure(self):
  114. """
  115. Test removing a capability which fails with DISM
  116. """
  117. expected = {
  118. "comment": "Failed to remove Capa2: Failed",
  119. "changes": {},
  120. "name": "Capa2",
  121. "result": False,
  122. }
  123. mock_removed = MagicMock(side_effect=[["Capa1", "Capa2"], ["Capa1", "Capa2"]])
  124. mock_remove = MagicMock(return_value={"retcode": 67, "stdout": "Failed"})
  125. with patch.dict(
  126. dism.__salt__,
  127. {
  128. "dism.installed_capabilities": mock_removed,
  129. "dism.remove_capability": mock_remove,
  130. },
  131. ):
  132. with patch.dict(dism.__opts__, {"test": False}):
  133. out = dism.capability_removed("Capa2")
  134. mock_removed.assert_called_with()
  135. mock_remove.assert_called_once_with("Capa2", None, False)
  136. self.assertEqual(out, expected)
  137. def test_capability_removed_removed(self):
  138. """
  139. Test removing a capability already removed
  140. """
  141. expected = {
  142. "comment": "The capability Capa2 is already removed",
  143. "changes": {},
  144. "name": "Capa2",
  145. "result": True,
  146. }
  147. mock_removed = MagicMock(return_value=["Capa1"])
  148. mock_remove = MagicMock()
  149. with patch.dict(
  150. dism.__salt__,
  151. {
  152. "dism.installed_capabilities": mock_removed,
  153. "dism.add_capability": mock_remove,
  154. },
  155. ):
  156. out = dism.capability_removed("Capa2", "somewhere", True)
  157. mock_removed.assert_called_once_with()
  158. assert not mock_remove.called
  159. self.assertEqual(out, expected)
  160. def test_feature_installed(self):
  161. """
  162. Test installing a feature with DISM
  163. """
  164. expected = {
  165. "comment": "Installed Feat2",
  166. "changes": {"feature": {"new": ["Feat2"]}, "retcode": 0},
  167. "name": "Feat2",
  168. "result": True,
  169. }
  170. mock_installed = MagicMock(side_effect=[["Feat1"], ["Feat1", "Feat2"]])
  171. mock_add = MagicMock(return_value={"retcode": 0})
  172. with patch.dict(
  173. dism.__salt__,
  174. {"dism.installed_features": mock_installed, "dism.add_feature": mock_add},
  175. ):
  176. with patch.dict(dism.__opts__, {"test": False}):
  177. out = dism.feature_installed("Feat2")
  178. mock_installed.assert_called_with()
  179. mock_add.assert_called_once_with(
  180. "Feat2", None, None, False, False, None, False
  181. )
  182. self.assertEqual(out, expected)
  183. def test_feature_installed_failure(self):
  184. """
  185. Test installing a feature which fails with DISM
  186. """
  187. expected = {
  188. "comment": "Failed to install Feat2: Failed",
  189. "changes": {},
  190. "name": "Feat2",
  191. "result": False,
  192. }
  193. mock_installed = MagicMock(side_effect=[["Feat1"], ["Feat1"]])
  194. mock_add = MagicMock(return_value={"retcode": 67, "stdout": "Failed"})
  195. with patch.dict(
  196. dism.__salt__,
  197. {"dism.installed_features": mock_installed, "dism.add_feature": mock_add},
  198. ):
  199. with patch.dict(dism.__opts__, {"test": False}):
  200. out = dism.feature_installed("Feat2")
  201. mock_installed.assert_called_with()
  202. mock_add.assert_called_once_with(
  203. "Feat2", None, None, False, False, None, False
  204. )
  205. self.assertEqual(out, expected)
  206. def test_feature_installed_installed(self):
  207. """
  208. Test installing a feature already installed
  209. """
  210. expected = {
  211. "comment": "The feature Feat1 is already installed",
  212. "changes": {},
  213. "name": "Feat1",
  214. "result": True,
  215. }
  216. mock_installed = MagicMock(side_effect=[["Feat1", "Feat2"], ["Feat1", "Feat2"]])
  217. mock_add = MagicMock()
  218. with patch.dict(
  219. dism.__salt__,
  220. {"dism.installed_features": mock_installed, "dism.add_feature": mock_add},
  221. ):
  222. out = dism.feature_installed("Feat1")
  223. mock_installed.assert_called_once_with()
  224. assert not mock_add.called
  225. self.assertEqual(out, expected)
  226. def test_feature_removed(self):
  227. """
  228. Test removing a feature with DISM
  229. """
  230. expected = {
  231. "comment": "Removed Feat2",
  232. "changes": {"feature": {"old": ["Feat2"]}, "retcode": 0},
  233. "name": "Feat2",
  234. "result": True,
  235. }
  236. mock_removed = MagicMock(side_effect=[["Feat1", "Feat2"], ["Feat1"]])
  237. mock_remove = MagicMock(return_value={"retcode": 0})
  238. with patch.dict(
  239. dism.__salt__,
  240. {
  241. "dism.installed_features": mock_removed,
  242. "dism.remove_feature": mock_remove,
  243. },
  244. ):
  245. with patch.dict(dism.__opts__, {"test": False}):
  246. out = dism.feature_removed("Feat2")
  247. mock_removed.assert_called_with()
  248. mock_remove.assert_called_once_with("Feat2", False, None, False)
  249. self.assertEqual(out, expected)
  250. def test_feature_removed_failure(self):
  251. """
  252. Test removing a feature which fails with DISM
  253. """
  254. expected = {
  255. "comment": "Failed to remove Feat2: Failed",
  256. "changes": {},
  257. "name": "Feat2",
  258. "result": False,
  259. }
  260. mock_removed = MagicMock(side_effect=[["Feat1", "Feat2"], ["Feat1", "Feat2"]])
  261. mock_remove = MagicMock(return_value={"retcode": 67, "stdout": "Failed"})
  262. with patch.dict(
  263. dism.__salt__,
  264. {
  265. "dism.installed_features": mock_removed,
  266. "dism.remove_feature": mock_remove,
  267. },
  268. ):
  269. with patch.dict(dism.__opts__, {"test": False}):
  270. out = dism.feature_removed("Feat2")
  271. mock_removed.assert_called_with()
  272. mock_remove.assert_called_once_with("Feat2", False, None, False)
  273. self.assertEqual(out, expected)
  274. def test_feature_removed_removed(self):
  275. """
  276. Test removing a feature already removed
  277. """
  278. expected = {
  279. "comment": "The feature Feat2 is already removed",
  280. "changes": {},
  281. "name": "Feat2",
  282. "result": True,
  283. }
  284. mock_removed = MagicMock(side_effect=[["Feat1"], ["Feat1"]])
  285. mock_remove = MagicMock()
  286. with patch.dict(
  287. dism.__salt__,
  288. {
  289. "dism.installed_features": mock_removed,
  290. "dism.remove_feature": mock_remove,
  291. },
  292. ):
  293. out = dism.feature_removed("Feat2")
  294. mock_removed.assert_called_once_with()
  295. assert not mock_remove.called
  296. self.assertEqual(out, expected)
  297. def test_package_installed(self):
  298. """
  299. Test installing a package with DISM
  300. """
  301. expected = {
  302. "comment": "Installed Pack2",
  303. "changes": {"package": {"new": ["Pack2"]}, "retcode": 0},
  304. "name": "Pack2",
  305. "result": True,
  306. }
  307. mock_installed = MagicMock(side_effect=[["Pack1"], ["Pack1", "Pack2"]])
  308. mock_add = MagicMock(return_value={"retcode": 0})
  309. mock_info = MagicMock(return_value={"Package Identity": "Pack2"})
  310. with patch.dict(
  311. dism.__salt__,
  312. {
  313. "dism.installed_packages": mock_installed,
  314. "dism.add_package": mock_add,
  315. "dism.package_info": mock_info,
  316. },
  317. ):
  318. with patch.dict(dism.__opts__, {"test": False}):
  319. with patch("os.path.exists"):
  320. out = dism.package_installed("Pack2")
  321. mock_installed.assert_called_with()
  322. mock_add.assert_called_once_with("Pack2", False, False, None, False)
  323. self.assertEqual(out, expected)
  324. def test_package_installed_failure(self):
  325. """
  326. Test installing a package which fails with DISM
  327. """
  328. expected = {
  329. "comment": "Failed to install Pack2: Failed",
  330. "changes": {},
  331. "name": "Pack2",
  332. "result": False,
  333. }
  334. mock_installed = MagicMock(side_effect=[["Pack1"], ["Pack1"]])
  335. mock_add = MagicMock(return_value={"retcode": 67, "stdout": "Failed"})
  336. mock_info = MagicMock(return_value={"Package Identity": "Pack2"})
  337. with patch.dict(
  338. dism.__salt__,
  339. {
  340. "dism.installed_packages": mock_installed,
  341. "dism.add_package": mock_add,
  342. "dism.package_info": mock_info,
  343. },
  344. ):
  345. with patch.dict(dism.__opts__, {"test": False}):
  346. with patch("os.path.exists"):
  347. out = dism.package_installed("Pack2")
  348. mock_installed.assert_called_with()
  349. mock_add.assert_called_once_with("Pack2", False, False, None, False)
  350. self.assertEqual(out, expected)
  351. def test_package_installed_installed(self):
  352. """
  353. Test installing a package already installed
  354. """
  355. expected = {
  356. "comment": "The package Pack2 is already installed: Pack2",
  357. "changes": {},
  358. "name": "Pack2",
  359. "result": True,
  360. }
  361. mock_installed = MagicMock(side_effect=[["Pack1", "Pack2"], ["Pack1", "Pack2"]])
  362. mock_add = MagicMock()
  363. mock_info = MagicMock(return_value={"Package Identity": "Pack2"})
  364. with patch.dict(
  365. dism.__salt__,
  366. {
  367. "dism.installed_packages": mock_installed,
  368. "dism.add_package": mock_add,
  369. "dism.package_info": mock_info,
  370. },
  371. ):
  372. with patch.dict(dism.__opts__, {"test": False}):
  373. with patch("os.path.exists"):
  374. out = dism.package_installed("Pack2")
  375. mock_installed.assert_called_once_with()
  376. assert not mock_add.called
  377. self.assertEqual(out, expected)
  378. def test_package_removed(self):
  379. """
  380. Test removing a package with DISM
  381. """
  382. expected = {
  383. "comment": "Removed Pack2",
  384. "changes": {"package": {"old": ["Pack2"]}, "retcode": 0},
  385. "name": "Pack2",
  386. "result": True,
  387. }
  388. mock_removed = MagicMock(side_effect=[["Pack1", "Pack2"], ["Pack1"]])
  389. mock_remove = MagicMock(return_value={"retcode": 0})
  390. mock_info = MagicMock(return_value={"Package Identity": "Pack2"})
  391. with patch.dict(
  392. dism.__salt__,
  393. {
  394. "dism.installed_packages": mock_removed,
  395. "dism.remove_package": mock_remove,
  396. "dism.package_info": mock_info,
  397. },
  398. ):
  399. with patch.dict(dism.__opts__, {"test": False}):
  400. with patch("os.path.exists"):
  401. out = dism.package_removed("Pack2")
  402. mock_removed.assert_called_with()
  403. mock_remove.assert_called_once_with("Pack2", None, False)
  404. self.assertEqual(out, expected)
  405. def test_package_removed_failure(self):
  406. """
  407. Test removing a package which fails with DISM
  408. """
  409. expected = {
  410. "comment": "Failed to remove Pack2: Failed",
  411. "changes": {},
  412. "name": "Pack2",
  413. "result": False,
  414. }
  415. mock_removed = MagicMock(side_effect=[["Pack1", "Pack2"], ["Pack1", "Pack2"]])
  416. mock_remove = MagicMock(return_value={"retcode": 67, "stdout": "Failed"})
  417. mock_info = MagicMock(return_value={"Package Identity": "Pack2"})
  418. with patch.dict(
  419. dism.__salt__,
  420. {
  421. "dism.installed_packages": mock_removed,
  422. "dism.remove_package": mock_remove,
  423. "dism.package_info": mock_info,
  424. },
  425. ):
  426. with patch.dict(dism.__opts__, {"test": False}):
  427. with patch("os.path.exists"):
  428. out = dism.package_removed("Pack2")
  429. mock_removed.assert_called_with()
  430. mock_remove.assert_called_once_with("Pack2", None, False)
  431. self.assertEqual(out, expected)
  432. def test_package_removed_removed(self):
  433. """
  434. Test removing a package already removed
  435. """
  436. expected = {
  437. "comment": "The package Pack2 is already removed",
  438. "changes": {},
  439. "name": "Pack2",
  440. "result": True,
  441. }
  442. mock_removed = MagicMock(side_effect=[["Pack1"], ["Pack1"]])
  443. mock_remove = MagicMock()
  444. mock_info = MagicMock(return_value={"Package Identity": "Pack2"})
  445. with patch.dict(
  446. dism.__salt__,
  447. {
  448. "dism.installed_packages": mock_removed,
  449. "dism.remove_package": mock_remove,
  450. "dism.package_info": mock_info,
  451. },
  452. ):
  453. with patch.dict(dism.__opts__, {"test": False}):
  454. with patch("os.path.exists"):
  455. out = dism.package_removed("Pack2")
  456. mock_removed.assert_called_once_with()
  457. assert not mock_remove.called
  458. self.assertEqual(out, expected)