test_win_file.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. # -*- coding: utf-8 -*-
  2. '''
  3. :codeauthor: Shane Lee <slee@saltstack.com>
  4. '''
  5. # Import Python Libs
  6. from __future__ import absolute_import, unicode_literals, print_function
  7. import os
  8. import sys
  9. # Import Salt Testing Libs
  10. from tests.support.mixins import LoaderModuleMockMixin
  11. from tests.support.mock import MagicMock, patch
  12. from tests.support.unit import TestCase, skipIf
  13. from tests.support.runtime import RUNTIME_VARS
  14. # Import Salt Libs
  15. import salt.modules.temp as temp
  16. import salt.modules.win_file as win_file
  17. import salt.utils.platform
  18. import salt.utils.win_dacl as win_dacl
  19. import salt.modules.cmdmod as cmdmod
  20. from salt.exceptions import CommandExecutionError
  21. try:
  22. WIN_VER = sys.getwindowsversion().major
  23. except AttributeError:
  24. WIN_VER = 0
  25. class DummyStat(object):
  26. st_mode = 33188
  27. st_ino = 115331251
  28. st_dev = 44
  29. st_nlink = 1
  30. st_uid = 99200001
  31. st_gid = 99200001
  32. st_size = 41743
  33. st_atime = 1552661253
  34. st_mtime = 1552661253
  35. st_ctime = 1552661253
  36. class WinFileTestCase(TestCase, LoaderModuleMockMixin):
  37. '''
  38. Test cases for salt.modules.win_file
  39. '''
  40. FAKE_RET = {'fake': 'ret data'}
  41. if salt.utils.platform.is_windows():
  42. FAKE_PATH = os.sep.join(['C:', 'path', 'does', 'not', 'exist'])
  43. else:
  44. FAKE_PATH = os.sep.join(['path', 'does', 'not', 'exist'])
  45. def setup_loader_modules(self):
  46. return {
  47. win_file: {
  48. '__utils__': {'dacl.set_perms': win_dacl.set_perms},
  49. '__salt__': {'cmd.run_stdout': cmdmod.run_stdout}
  50. }
  51. }
  52. def test_issue_43328_stats(self):
  53. '''
  54. Make sure that a CommandExecutionError is raised if the file does NOT
  55. exist
  56. '''
  57. with patch('os.path.exists', return_value=False):
  58. self.assertRaises(CommandExecutionError,
  59. win_file.stats,
  60. self.FAKE_PATH)
  61. def test_issue_43328_check_perms_no_ret(self):
  62. '''
  63. Make sure that a CommandExecutionError is raised if the file does NOT
  64. exist
  65. '''
  66. with patch('os.path.exists', return_value=False):
  67. self.assertRaises(
  68. CommandExecutionError, win_file.check_perms, self.FAKE_PATH)
  69. @skipIf(not salt.utils.platform.is_windows(), 'Skip on Non-Windows systems')
  70. @skipIf(WIN_VER < 6, 'Symlinks not supported on Vista an lower')
  71. def test_issue_52002_check_file_remove_symlink(self):
  72. '''
  73. Make sure that directories including symlinks or symlinks can be removed
  74. '''
  75. base = temp.dir(prefix='base-', parent=RUNTIME_VARS.TMP)
  76. target = os.path.join(base, 'child 1', 'target\\')
  77. symlink = os.path.join(base, 'child 2', 'link')
  78. try:
  79. # Create environment
  80. self.assertFalse(win_file.directory_exists(target))
  81. self.assertFalse(win_file.directory_exists(symlink))
  82. self.assertTrue(win_file.makedirs_(target))
  83. self.assertTrue(win_file.makedirs_(symlink))
  84. self.assertTrue(win_file.symlink(target, symlink))
  85. self.assertTrue(win_file.directory_exists(symlink))
  86. self.assertTrue(win_file.is_link(symlink))
  87. # Test removal of directory containing symlink
  88. self.assertTrue(win_file.remove(base))
  89. self.assertFalse(win_file.directory_exists(base))
  90. finally:
  91. if os.path.exists(base):
  92. win_file.remove(base)
  93. @skipIf(not salt.utils.platform.is_windows(), 'Skip on Non-Windows systems')
  94. class WinFileCheckPermsTestCase(TestCase, LoaderModuleMockMixin):
  95. '''
  96. Test cases for the check_perms function in salt.modules.win_file
  97. '''
  98. temp_file = ''
  99. current_user = ''
  100. def setup_loader_modules(self):
  101. self.current_user = salt.utils.win_functions.get_current_user(False)
  102. return {
  103. win_file: {
  104. '__utils__': {'dacl.check_perms': win_dacl.check_perms,
  105. 'dacl.set_perms': win_dacl.set_perms}
  106. },
  107. win_dacl: {
  108. '__opts__': {'test': False},
  109. }
  110. }
  111. def setUp(self):
  112. self.temp_file = temp.file(parent=RUNTIME_VARS.TMP)
  113. salt.utils.win_dacl.set_owner(obj_name=self.temp_file,
  114. principal=self.current_user)
  115. salt.utils.win_dacl.set_inheritance(obj_name=self.temp_file,
  116. enabled=True)
  117. self.assertEqual(
  118. salt.utils.win_dacl.get_owner(obj_name=self.temp_file),
  119. self.current_user)
  120. def tearDown(self):
  121. os.remove(self.temp_file)
  122. def test_check_perms_set_owner_test_true(self):
  123. '''
  124. Test setting the owner of a file with test=True
  125. '''
  126. expected = {'comment': '',
  127. 'changes': {'owner': 'Administrators'},
  128. 'name': self.temp_file,
  129. 'result': None}
  130. with patch.dict(win_dacl.__opts__, {'test': True}):
  131. ret = win_file.check_perms(path=self.temp_file,
  132. owner='Administrators',
  133. inheritance=None)
  134. self.assertDictEqual(expected, ret)
  135. def test_check_perms_set_owner(self):
  136. '''
  137. Test setting the owner of a file
  138. '''
  139. expected = {'comment': '',
  140. 'changes': {'owner': 'Administrators'},
  141. 'name': self.temp_file,
  142. 'result': True}
  143. ret = win_file.check_perms(path=self.temp_file,
  144. owner='Administrators',
  145. inheritance=None)
  146. self.assertDictEqual(expected, ret)
  147. def test_check_perms_deny_test_true(self):
  148. '''
  149. Test setting deny perms on a file with test=True
  150. '''
  151. expected = {'comment': '',
  152. 'changes': {'perms': {'Users': {'deny': 'read_execute'}}},
  153. 'name': self.temp_file,
  154. 'result': None}
  155. with patch.dict(win_dacl.__opts__, {'test': True}):
  156. ret = win_file.check_perms(
  157. path=self.temp_file,
  158. deny_perms={'Users': {'perms': 'read_execute'}},
  159. inheritance=None)
  160. self.assertDictEqual(expected, ret)
  161. def test_check_perms_deny(self):
  162. '''
  163. Test setting deny perms on a file
  164. '''
  165. expected = {'comment': '',
  166. 'changes': {'perms': {'Users': {'deny': 'read_execute'}}},
  167. 'name': self.temp_file,
  168. 'result': True}
  169. ret = win_file.check_perms(
  170. path=self.temp_file,
  171. deny_perms={'Users': {'perms': 'read_execute'}},
  172. inheritance=None)
  173. self.assertDictEqual(expected, ret)
  174. def test_check_perms_grant_test_true(self):
  175. '''
  176. Test setting grant perms on a file with test=True
  177. '''
  178. expected = {'comment': '',
  179. 'changes': {'perms': {'Users': {'grant': 'read_execute'}}},
  180. 'name': self.temp_file,
  181. 'result': None}
  182. with patch.dict(win_dacl.__opts__, {'test': True}):
  183. ret = win_file.check_perms(
  184. path=self.temp_file,
  185. grant_perms={'Users': {'perms': 'read_execute'}},
  186. inheritance=None)
  187. self.assertDictEqual(expected, ret)
  188. def test_check_perms_grant(self):
  189. '''
  190. Test setting grant perms on a file
  191. '''
  192. expected = {'comment': '',
  193. 'changes': {'perms': {'Users': {'grant': 'read_execute'}}},
  194. 'name': self.temp_file,
  195. 'result': True}
  196. ret = win_file.check_perms(
  197. path=self.temp_file,
  198. grant_perms={'Users': {'perms': 'read_execute'}},
  199. inheritance=None)
  200. self.assertDictEqual(expected, ret)
  201. def test_check_perms_inheritance_false_test_true(self):
  202. '''
  203. Test setting inheritance to False with test=True
  204. '''
  205. expected = {'comment': '',
  206. 'changes': {'inheritance': False},
  207. 'name': self.temp_file,
  208. 'result': None}
  209. with patch.dict(win_dacl.__opts__, {'test': True}):
  210. ret = win_file.check_perms(path=self.temp_file,
  211. inheritance=False)
  212. self.assertDictEqual(expected, ret)
  213. def test_check_perms_inheritance_false(self):
  214. '''
  215. Test setting inheritance to False
  216. '''
  217. expected = {'comment': '',
  218. 'changes': {'inheritance': False},
  219. 'name': self.temp_file,
  220. 'result': True}
  221. ret = win_file.check_perms(path=self.temp_file,
  222. inheritance=False)
  223. self.assertDictEqual(expected, ret)
  224. def test_check_perms_inheritance_true(self):
  225. '''
  226. Test setting inheritance to true when it's already true (default)
  227. '''
  228. expected = {'comment': '',
  229. 'changes': {},
  230. 'name': self.temp_file,
  231. 'result': True}
  232. ret = win_file.check_perms(path=self.temp_file,
  233. inheritance=True)
  234. self.assertDictEqual(expected, ret)
  235. def test_check_perms_reset_test_true(self):
  236. '''
  237. Test resetting perms with test=True. This shows minimal changes
  238. '''
  239. # Turn off inheritance
  240. salt.utils.win_dacl.set_inheritance(obj_name=self.temp_file,
  241. enabled=False,
  242. clear=True)
  243. # Set some permissions
  244. salt.utils.win_dacl.set_permissions(obj_name=self.temp_file,
  245. principal='Administrator',
  246. permissions='full_control')
  247. expected = {'comment': '',
  248. 'changes': {
  249. 'perms': {
  250. 'Administrators': {'grant': 'full_control'},
  251. 'Users': {'grant': 'read_execute'}},
  252. 'remove_perms': {
  253. 'Administrator': {
  254. 'grant': {'applies to': 'Not Inherited (file)',
  255. 'permissions': 'Full control'}}}},
  256. 'name': self.temp_file,
  257. 'result': None}
  258. with patch.dict(win_dacl.__opts__, {'test': True}):
  259. ret = win_file.check_perms(
  260. path=self.temp_file,
  261. grant_perms={'Users': {'perms': 'read_execute'},
  262. 'Administrators': {'perms': 'full_control'}},
  263. inheritance=False,
  264. reset=True)
  265. self.assertDictEqual(expected, ret)
  266. def test_check_perms_reset(self):
  267. '''
  268. Test resetting perms on a File
  269. '''
  270. # Turn off inheritance
  271. salt.utils.win_dacl.set_inheritance(obj_name=self.temp_file,
  272. enabled=False,
  273. clear=True)
  274. # Set some permissions
  275. salt.utils.win_dacl.set_permissions(obj_name=self.temp_file,
  276. principal='Administrator',
  277. permissions='full_control')
  278. expected = {'comment': '',
  279. 'changes': {
  280. 'perms': {
  281. 'Administrators': {'grant': 'full_control'},
  282. 'Users': {'grant': 'read_execute'}},
  283. 'remove_perms': {
  284. 'Administrator': {
  285. 'grant': {'applies to': 'Not Inherited (file)',
  286. 'permissions': 'Full control'}}}},
  287. 'name': self.temp_file,
  288. 'result': True}
  289. ret = win_file.check_perms(
  290. path=self.temp_file,
  291. grant_perms={'Users': {'perms': 'read_execute'},
  292. 'Administrators': {'perms': 'full_control'}},
  293. inheritance=False,
  294. reset=True)
  295. self.assertDictEqual(expected, ret)
  296. def test_stat(self):
  297. with patch('os.path.exists', MagicMock(return_value=True)), \
  298. patch('salt.modules.win_file._resolve_symlink', MagicMock(side_effect=lambda path: path)), \
  299. patch('salt.modules.win_file.get_uid', MagicMock(return_value=1)), \
  300. patch('salt.modules.win_file.uid_to_user', MagicMock(return_value='dummy')), \
  301. patch('salt.modules.win_file.get_pgid', MagicMock(return_value=1)), \
  302. patch('salt.modules.win_file.gid_to_group', MagicMock(return_value='dummy')), \
  303. patch('os.stat', MagicMock(return_value=DummyStat())):
  304. ret = win_file.stats('dummy', None, True)
  305. self.assertEqual(ret['mode'], '0644')
  306. self.assertEqual(ret['type'], 'file')