test_win_reg.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import, print_function, unicode_literals
  3. import salt.utils.stringutils
  4. import salt.utils.win_reg as win_reg
  5. from salt.exceptions import CommandExecutionError
  6. from salt.ext import six
  7. from tests.support.helpers import destructiveTest, random_string
  8. from tests.support.mock import MagicMock, patch
  9. from tests.support.unit import TestCase, skipIf
  10. try:
  11. import win32api
  12. HAS_WIN32 = True
  13. except ImportError:
  14. HAS_WIN32 = False
  15. UNICODE_KEY = "Unicode Key \N{TRADE MARK SIGN}"
  16. UNICODE_VALUE = (
  17. "Unicode Value " "\N{COPYRIGHT SIGN},\N{TRADE MARK SIGN},\N{REGISTERED SIGN}"
  18. )
  19. FAKE_KEY = "SOFTWARE\\{0}".format(random_string("SaltTesting-", lowercase=False))
  20. @skipIf(not HAS_WIN32, "Tests require win32 libraries")
  21. class WinFunctionsTestCase(TestCase):
  22. """
  23. Test cases for salt.utils.win_reg
  24. """
  25. def test_broadcast_change_success(self):
  26. """
  27. Tests the broadcast_change function
  28. """
  29. with patch("win32gui.SendMessageTimeout", return_value=("", 0)):
  30. self.assertTrue(win_reg.broadcast_change())
  31. def test_broadcast_change_fail(self):
  32. """
  33. Tests the broadcast_change function failure
  34. """
  35. with patch("win32gui.SendMessageTimeout", return_value=("", 1)):
  36. self.assertFalse(win_reg.broadcast_change())
  37. def test_key_exists_existing(self):
  38. """
  39. Tests the key_exists function using a well known registry key
  40. """
  41. self.assertTrue(win_reg.key_exists(hive="HKLM", key="SOFTWARE\\Microsoft"))
  42. def test_key_exists_non_existing(self):
  43. """
  44. Tests the key_exists function using a non existing registry key
  45. """
  46. self.assertFalse(win_reg.key_exists(hive="HKLM", key=FAKE_KEY))
  47. def test_key_exists_invalid_hive(self):
  48. """
  49. Tests the key_exists function using an invalid hive
  50. """
  51. self.assertRaises(
  52. CommandExecutionError,
  53. win_reg.key_exists,
  54. hive="BADHIVE",
  55. key="SOFTWARE\\Microsoft",
  56. )
  57. def test_key_exists_unknown_key_error(self):
  58. """
  59. Tests the key_exists function with an unknown key error
  60. """
  61. mock_error = MagicMock(
  62. side_effect=win32api.error(123, "RegOpenKeyEx", "Unknown error")
  63. )
  64. with patch("salt.utils.win_reg.win32api.RegOpenKeyEx", mock_error):
  65. self.assertRaises(
  66. win32api.error,
  67. win_reg.key_exists,
  68. hive="HKLM",
  69. key="SOFTWARE\\Microsoft",
  70. )
  71. def test_value_exists_existing(self):
  72. """
  73. Tests the value_exists function using a well known registry key
  74. """
  75. self.assertTrue(
  76. win_reg.value_exists(
  77. hive="HKLM",
  78. key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  79. vname="CommonFilesDir",
  80. )
  81. )
  82. def test_value_exists_non_existing(self):
  83. """
  84. Tests the value_exists function using a non existing registry key
  85. """
  86. self.assertFalse(
  87. win_reg.value_exists(
  88. hive="HKLM",
  89. key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  90. vname="NonExistingValueName",
  91. )
  92. )
  93. def test_value_exists_invalid_hive(self):
  94. """
  95. Tests the value_exists function using an invalid hive
  96. """
  97. self.assertRaises(
  98. CommandExecutionError,
  99. win_reg.value_exists,
  100. hive="BADHIVE",
  101. key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  102. vname="CommonFilesDir",
  103. )
  104. def test_value_exists_key_not_exist(self):
  105. """
  106. Tests the value_exists function when the key does not exist
  107. """
  108. mock_error = MagicMock(
  109. side_effect=win32api.error(2, "RegOpenKeyEx", "Unknown error")
  110. )
  111. with patch("salt.utils.win_reg.win32api.RegOpenKeyEx", mock_error):
  112. self.assertFalse(
  113. win_reg.value_exists(
  114. hive="HKLM",
  115. key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  116. vname="CommonFilesDir",
  117. )
  118. )
  119. def test_value_exists_unknown_key_error(self):
  120. """
  121. Tests the value_exists function with an unknown error when opening the
  122. key
  123. """
  124. mock_error = MagicMock(
  125. side_effect=win32api.error(123, "RegOpenKeyEx", "Unknown error")
  126. )
  127. with patch("salt.utils.win_reg.win32api.RegOpenKeyEx", mock_error):
  128. self.assertRaises(
  129. win32api.error,
  130. win_reg.value_exists,
  131. hive="HKLM",
  132. key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  133. vname="CommonFilesDir",
  134. )
  135. def test_value_exists_empty_default_value(self):
  136. """
  137. Tests the value_exists function when querying the default value
  138. """
  139. mock_error = MagicMock(
  140. side_effect=win32api.error(2, "RegQueryValueEx", "Empty Value")
  141. )
  142. with patch("salt.utils.win_reg.win32api.RegQueryValueEx", mock_error):
  143. self.assertTrue(
  144. win_reg.value_exists(
  145. hive="HKLM",
  146. key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  147. vname=None,
  148. )
  149. )
  150. def test_value_exists_no_vname(self):
  151. """
  152. Tests the value_exists function when the vname does not exist
  153. """
  154. mock_error = MagicMock(
  155. side_effect=win32api.error(123, "RegQueryValueEx", "Empty Value")
  156. )
  157. with patch("salt.utils.win_reg.win32api.RegQueryValueEx", mock_error):
  158. self.assertFalse(
  159. win_reg.value_exists(
  160. hive="HKLM",
  161. key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  162. vname="NonExistingValuePair",
  163. )
  164. )
  165. def test_list_keys_existing(self):
  166. """
  167. Test the list_keys function using a well known registry key
  168. """
  169. self.assertIn("Microsoft", win_reg.list_keys(hive="HKLM", key="SOFTWARE"))
  170. def test_list_keys_non_existing(self):
  171. """
  172. Test the list_keys function using a non existing registry key
  173. """
  174. expected = (False, "Cannot find key: HKLM\\{0}".format(FAKE_KEY))
  175. self.assertEqual(win_reg.list_keys(hive="HKLM", key=FAKE_KEY), expected)
  176. def test_list_keys_invalid_hive(self):
  177. """
  178. Test the list_keys function when passing an invalid hive
  179. """
  180. self.assertRaises(
  181. CommandExecutionError,
  182. win_reg.list_keys,
  183. hive="BADHIVE",
  184. key="SOFTWARE\\Microsoft",
  185. )
  186. def test_list_keys_unknown_key_error(self):
  187. """
  188. Tests the list_keys function with an unknown key error
  189. """
  190. mock_error = MagicMock(
  191. side_effect=win32api.error(123, "RegOpenKeyEx", "Unknown error")
  192. )
  193. with patch("salt.utils.win_reg.win32api.RegOpenKeyEx", mock_error):
  194. self.assertRaises(
  195. win32api.error,
  196. win_reg.list_keys,
  197. hive="HKLM",
  198. key="SOFTWARE\\Microsoft",
  199. )
  200. def test_list_values_existing(self):
  201. """
  202. Test the list_values function using a well known registry key
  203. """
  204. values = win_reg.list_values(
  205. hive="HKLM", key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion"
  206. )
  207. keys = []
  208. for value in values:
  209. keys.append(value["vname"])
  210. self.assertIn("ProgramFilesDir", keys)
  211. def test_list_values_non_existing(self):
  212. """
  213. Test the list_values function using a non existing registry key
  214. """
  215. expected = (False, "Cannot find key: HKLM\\{0}".format(FAKE_KEY))
  216. self.assertEqual(win_reg.list_values(hive="HKLM", key=FAKE_KEY), expected)
  217. def test_list_values_invalid_hive(self):
  218. """
  219. Test the list_values function when passing an invalid hive
  220. """
  221. self.assertRaises(
  222. CommandExecutionError,
  223. win_reg.list_values,
  224. hive="BADHIVE",
  225. key="SOFTWARE\\Microsoft",
  226. )
  227. def test_list_values_unknown_key_error(self):
  228. """
  229. Tests the list_values function with an unknown key error
  230. """
  231. mock_error = MagicMock(
  232. side_effect=win32api.error(123, "RegOpenKeyEx", "Unknown error")
  233. )
  234. with patch("salt.utils.win_reg.win32api.RegOpenKeyEx", mock_error):
  235. self.assertRaises(
  236. win32api.error,
  237. win_reg.list_values,
  238. hive="HKLM",
  239. key="SOFTWARE\\Microsoft",
  240. )
  241. def test_read_value_existing(self):
  242. """
  243. Test the read_value function using a well known registry value
  244. """
  245. ret = win_reg.read_value(
  246. hive="HKLM",
  247. key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  248. vname="ProgramFilesPath",
  249. )
  250. self.assertEqual(ret["vdata"], "%ProgramFiles%")
  251. def test_read_value_default(self):
  252. """
  253. Test the read_value function reading the default value using a well
  254. known registry key
  255. """
  256. ret = win_reg.read_value(
  257. hive="HKLM", key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion"
  258. )
  259. self.assertEqual(ret["vdata"], "(value not set)")
  260. def test_read_value_non_existing(self):
  261. """
  262. Test the read_value function using a non existing value pair
  263. """
  264. expected = {
  265. "comment": "Cannot find fake_name in HKLM\\SOFTWARE\\Microsoft\\"
  266. "Windows\\CurrentVersion",
  267. "vdata": None,
  268. "vname": "fake_name",
  269. "success": False,
  270. "hive": "HKLM",
  271. "key": "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  272. }
  273. self.assertDictEqual(
  274. win_reg.read_value(
  275. hive="HKLM",
  276. key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  277. vname="fake_name",
  278. ),
  279. expected,
  280. )
  281. def test_read_value_non_existing_key(self):
  282. """
  283. Test the read_value function using a non existing registry key
  284. """
  285. expected = {
  286. "comment": "Cannot find key: HKLM\\{0}".format(FAKE_KEY),
  287. "vdata": None,
  288. "vname": "fake_name",
  289. "success": False,
  290. "hive": "HKLM",
  291. "key": FAKE_KEY,
  292. }
  293. self.assertDictEqual(
  294. win_reg.read_value(hive="HKLM", key=FAKE_KEY, vname="fake_name"), expected
  295. )
  296. def test_read_value_invalid_hive(self):
  297. """
  298. Test the read_value function when passing an invalid hive
  299. """
  300. self.assertRaises(
  301. CommandExecutionError,
  302. win_reg.read_value,
  303. hive="BADHIVE",
  304. key="SOFTWARE\\Microsoft",
  305. vname="ProgramFilesPath",
  306. )
  307. def test_read_value_unknown_key_error(self):
  308. """
  309. Tests the read_value function with an unknown key error
  310. """
  311. mock_error = MagicMock(
  312. side_effect=win32api.error(123, "RegOpenKeyEx", "Unknown error")
  313. )
  314. with patch("salt.utils.win_reg.win32api.RegOpenKeyEx", mock_error):
  315. self.assertRaises(
  316. win32api.error,
  317. win_reg.read_value,
  318. hive="HKLM",
  319. key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  320. vname="ProgramFilesPath",
  321. )
  322. def test_read_value_unknown_value_error(self):
  323. """
  324. Tests the read_value function with an unknown value error
  325. """
  326. mock_error = MagicMock(
  327. side_effect=win32api.error(123, "RegQueryValueEx", "Unknown error")
  328. )
  329. with patch("salt.utils.win_reg.win32api.RegQueryValueEx", mock_error):
  330. self.assertRaises(
  331. win32api.error,
  332. win_reg.read_value,
  333. hive="HKLM",
  334. key="SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
  335. vname="ProgramFilesPath",
  336. )
  337. @destructiveTest
  338. def test_read_value_multi_sz_empty_list(self):
  339. """
  340. An empty REG_MULTI_SZ value should return an empty list, not None
  341. """
  342. try:
  343. self.assertTrue(
  344. win_reg.set_value(
  345. hive="HKLM",
  346. key=FAKE_KEY,
  347. vname="empty_list",
  348. vdata=[],
  349. vtype="REG_MULTI_SZ",
  350. )
  351. )
  352. expected = {
  353. "hive": "HKLM",
  354. "key": FAKE_KEY,
  355. "success": True,
  356. "vdata": [],
  357. "vname": "empty_list",
  358. "vtype": "REG_MULTI_SZ",
  359. }
  360. self.assertEqual(
  361. win_reg.read_value(hive="HKLM", key=FAKE_KEY, vname="empty_list",),
  362. expected,
  363. )
  364. finally:
  365. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  366. @destructiveTest
  367. def test_set_value(self):
  368. """
  369. Test the set_value function
  370. """
  371. try:
  372. self.assertTrue(
  373. win_reg.set_value(
  374. hive="HKLM", key=FAKE_KEY, vname="fake_name", vdata="fake_data"
  375. )
  376. )
  377. expected = {
  378. "hive": "HKLM",
  379. "key": FAKE_KEY,
  380. "success": True,
  381. "vdata": "fake_data",
  382. "vname": "fake_name",
  383. "vtype": "REG_SZ",
  384. }
  385. self.assertEqual(
  386. win_reg.read_value(hive="HKLM", key=FAKE_KEY, vname="fake_name"),
  387. expected,
  388. )
  389. finally:
  390. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  391. @destructiveTest
  392. def test_set_value_default(self):
  393. """
  394. Test the set_value function on the default value
  395. """
  396. try:
  397. self.assertTrue(
  398. win_reg.set_value(hive="HKLM", key=FAKE_KEY, vdata="fake_default_data")
  399. )
  400. expected = {
  401. "hive": "HKLM",
  402. "key": FAKE_KEY,
  403. "success": True,
  404. "vdata": "fake_default_data",
  405. "vname": "(Default)",
  406. "vtype": "REG_SZ",
  407. }
  408. self.assertEqual(win_reg.read_value(hive="HKLM", key=FAKE_KEY), expected)
  409. finally:
  410. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  411. @destructiveTest
  412. def test_set_value_unicode_key(self):
  413. """
  414. Test the set_value function on a unicode key
  415. """
  416. try:
  417. self.assertTrue(
  418. win_reg.set_value(
  419. hive="HKLM",
  420. key="\\".join([FAKE_KEY, UNICODE_KEY]),
  421. vname="fake_name",
  422. vdata="fake_value",
  423. )
  424. )
  425. expected = {
  426. "hive": "HKLM",
  427. "key": "\\".join([FAKE_KEY, UNICODE_KEY]),
  428. "success": True,
  429. "vdata": "fake_value",
  430. "vname": "fake_name",
  431. "vtype": "REG_SZ",
  432. }
  433. self.assertEqual(
  434. win_reg.read_value(
  435. hive="HKLM",
  436. key="\\".join([FAKE_KEY, UNICODE_KEY]),
  437. vname="fake_name",
  438. ),
  439. expected,
  440. )
  441. finally:
  442. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  443. @destructiveTest
  444. def test_set_value_unicode_value(self):
  445. """
  446. Test the set_value function on a unicode value
  447. """
  448. try:
  449. self.assertTrue(
  450. win_reg.set_value(
  451. hive="HKLM", key=FAKE_KEY, vname="fake_unicode", vdata=UNICODE_VALUE
  452. )
  453. )
  454. expected = {
  455. "hive": "HKLM",
  456. "key": FAKE_KEY,
  457. "success": True,
  458. "vdata": UNICODE_VALUE,
  459. "vname": "fake_unicode",
  460. "vtype": "REG_SZ",
  461. }
  462. self.assertEqual(
  463. win_reg.read_value(hive="HKLM", key=FAKE_KEY, vname="fake_unicode"),
  464. expected,
  465. )
  466. finally:
  467. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  468. @destructiveTest
  469. def test_set_value_reg_dword(self):
  470. """
  471. Test the set_value function on a REG_DWORD value
  472. """
  473. try:
  474. self.assertTrue(
  475. win_reg.set_value(
  476. hive="HKLM",
  477. key=FAKE_KEY,
  478. vname="dword_value",
  479. vdata=123,
  480. vtype="REG_DWORD",
  481. )
  482. )
  483. expected = {
  484. "hive": "HKLM",
  485. "key": FAKE_KEY,
  486. "success": True,
  487. "vdata": 123,
  488. "vname": "dword_value",
  489. "vtype": "REG_DWORD",
  490. }
  491. self.assertEqual(
  492. win_reg.read_value(hive="HKLM", key=FAKE_KEY, vname="dword_value"),
  493. expected,
  494. )
  495. finally:
  496. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  497. @destructiveTest
  498. def test_set_value_reg_qword(self):
  499. """
  500. Test the set_value function on a REG_QWORD value
  501. """
  502. try:
  503. self.assertTrue(
  504. win_reg.set_value(
  505. hive="HKLM",
  506. key=FAKE_KEY,
  507. vname="qword_value",
  508. vdata=123,
  509. vtype="REG_QWORD",
  510. )
  511. )
  512. expected = {
  513. "hive": "HKLM",
  514. "key": FAKE_KEY,
  515. "success": True,
  516. "vdata": 123,
  517. "vname": "qword_value",
  518. "vtype": "REG_QWORD",
  519. }
  520. self.assertEqual(
  521. win_reg.read_value(hive="HKLM", key=FAKE_KEY, vname="qword_value"),
  522. expected,
  523. )
  524. finally:
  525. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  526. def test_set_value_invalid_hive(self):
  527. """
  528. Test the set_value function when passing an invalid hive
  529. """
  530. self.assertRaises(
  531. CommandExecutionError,
  532. win_reg.set_value,
  533. hive="BADHIVE",
  534. key=FAKE_KEY,
  535. vname="fake_name",
  536. vdata="fake_data",
  537. )
  538. def test_set_value_open_create_failure(self):
  539. """
  540. Test the set_value function when there is a problem opening/creating
  541. the key
  542. """
  543. mock_error = MagicMock(
  544. side_effect=win32api.error(123, "RegCreateKeyEx", "Unknown error")
  545. )
  546. with patch("salt.utils.win_reg.win32api.RegCreateKeyEx", mock_error):
  547. self.assertFalse(
  548. win_reg.set_value(
  549. hive="HKLM", key=FAKE_KEY, vname="fake_name", vdata="fake_data"
  550. )
  551. )
  552. def test_set_value_type_error(self):
  553. """
  554. Test the set_value function when the wrong type of data is passed
  555. """
  556. mock_error = MagicMock(side_effect=TypeError("Mocked TypeError"))
  557. with patch("salt.utils.win_reg.win32api.RegSetValueEx", mock_error):
  558. self.assertFalse(
  559. win_reg.set_value(
  560. hive="HKLM", key=FAKE_KEY, vname="fake_name", vdata="fake_data"
  561. )
  562. )
  563. def test_set_value_system_error(self):
  564. """
  565. Test the set_value function when a SystemError occurs while setting the
  566. value
  567. """
  568. mock_error = MagicMock(side_effect=SystemError("Mocked SystemError"))
  569. with patch("salt.utils.win_reg.win32api.RegSetValueEx", mock_error):
  570. self.assertFalse(
  571. win_reg.set_value(
  572. hive="HKLM", key=FAKE_KEY, vname="fake_name", vdata="fake_data"
  573. )
  574. )
  575. def test_set_value_value_error(self):
  576. """
  577. Test the set_value function when a ValueError occurs while setting the
  578. value
  579. """
  580. mock_error = MagicMock(side_effect=ValueError("Mocked ValueError"))
  581. with patch("salt.utils.win_reg.win32api.RegSetValueEx", mock_error):
  582. self.assertFalse(
  583. win_reg.set_value(
  584. hive="HKLM", key=FAKE_KEY, vname="fake_name", vdata="fake_data"
  585. )
  586. )
  587. def test_cast_vdata_reg_binary(self):
  588. """
  589. Test the cast_vdata function with REG_BINARY
  590. Should always return binary data
  591. """
  592. vdata = salt.utils.stringutils.to_bytes("test data")
  593. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_BINARY")
  594. self.assertTrue(isinstance(result, six.binary_type))
  595. vdata = salt.utils.stringutils.to_str("test data")
  596. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_BINARY")
  597. self.assertTrue(isinstance(result, six.binary_type))
  598. vdata = salt.utils.stringutils.to_unicode("test data")
  599. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_BINARY")
  600. self.assertTrue(isinstance(result, six.binary_type))
  601. def test_cast_vdata_reg_dword(self):
  602. """
  603. Test the cast_vdata function with REG_DWORD
  604. Should always return integer
  605. """
  606. vdata = 1
  607. expected = 1
  608. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_DWORD")
  609. self.assertEqual(result, expected)
  610. vdata = "1"
  611. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_DWORD")
  612. self.assertEqual(result, expected)
  613. vdata = "0000001"
  614. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_DWORD")
  615. self.assertEqual(result, expected)
  616. def test_cast_vdata_reg_expand_sz(self):
  617. """
  618. Test the cast_vdata function with REG_EXPAND_SZ
  619. Should always return unicode
  620. """
  621. vdata = salt.utils.stringutils.to_str("test data")
  622. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_EXPAND_SZ")
  623. self.assertTrue(isinstance(result, six.text_type))
  624. vdata = salt.utils.stringutils.to_bytes("test data")
  625. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_EXPAND_SZ")
  626. self.assertTrue(isinstance(result, six.text_type))
  627. def test_cast_vdata_reg_multi_sz(self):
  628. """
  629. Test the cast_vdata function with REG_MULTI_SZ
  630. Should always return a list of unicode strings
  631. """
  632. vdata = [
  633. salt.utils.stringutils.to_str("test string"),
  634. salt.utils.stringutils.to_bytes("test bytes"),
  635. ]
  636. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_MULTI_SZ")
  637. self.assertTrue(isinstance(result, list))
  638. for item in result:
  639. self.assertTrue(isinstance(item, six.text_type))
  640. def test_cast_vdata_reg_qword(self):
  641. """
  642. Test the cast_vdata function with REG_QWORD
  643. Should always return a long integer
  644. `int` is `long` is default on Py3
  645. """
  646. vdata = 1
  647. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_QWORD")
  648. if six.PY2:
  649. # pylint: disable=incompatible-py3-code,undefined-variable
  650. self.assertTrue(isinstance(result, long))
  651. # pylint: enable=incompatible-py3-code,undefined-variable
  652. else:
  653. self.assertTrue(isinstance(result, int))
  654. vdata = "1"
  655. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_QWORD")
  656. if six.PY2:
  657. # pylint: disable=incompatible-py3-code,undefined-variable
  658. self.assertTrue(isinstance(result, long))
  659. # pylint: enable=incompatible-py3-code,undefined-variable
  660. else:
  661. self.assertTrue(isinstance(result, int))
  662. def test_cast_vdata_reg_sz(self):
  663. """
  664. Test the cast_vdata function with REG_SZ
  665. Should always return unicode
  666. """
  667. vdata = salt.utils.stringutils.to_str("test data")
  668. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_SZ")
  669. self.assertTrue(isinstance(result, six.text_type))
  670. vdata = salt.utils.stringutils.to_bytes("test data")
  671. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_SZ")
  672. self.assertTrue(isinstance(result, six.text_type))
  673. vdata = None
  674. result = win_reg.cast_vdata(vdata=vdata, vtype="REG_SZ")
  675. self.assertTrue(isinstance(result, six.text_type))
  676. self.assertEqual(result, "")
  677. @destructiveTest
  678. def test_delete_value(self):
  679. """
  680. Test the delete_value function
  681. """
  682. try:
  683. self.assertTrue(
  684. win_reg.set_value(
  685. hive="HKLM", key=FAKE_KEY, vname="fake_name", vdata="fake_data"
  686. )
  687. )
  688. self.assertTrue(
  689. win_reg.delete_value(hive="HKLM", key=FAKE_KEY, vname="fake_name")
  690. )
  691. finally:
  692. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  693. def test_delete_value_non_existing(self):
  694. """
  695. Test the delete_value function on non existing value
  696. """
  697. mock_error = MagicMock(
  698. side_effect=win32api.error(2, "RegOpenKeyEx", "Unknown error")
  699. )
  700. with patch("salt.utils.win_reg.win32api.RegOpenKeyEx", mock_error):
  701. self.assertIsNone(
  702. win_reg.delete_value(hive="HKLM", key=FAKE_KEY, vname="fake_name")
  703. )
  704. def test_delete_value_invalid_hive(self):
  705. """
  706. Test the delete_value function when passing an invalid hive
  707. """
  708. self.assertRaises(
  709. CommandExecutionError,
  710. win_reg.delete_value,
  711. hive="BADHIVE",
  712. key=FAKE_KEY,
  713. vname="fake_name",
  714. )
  715. def test_delete_value_unknown_error(self):
  716. """
  717. Test the delete_value function when there is a problem opening the key
  718. """
  719. mock_error = MagicMock(
  720. side_effect=win32api.error(123, "RegOpenKeyEx", "Unknown error")
  721. )
  722. with patch("salt.utils.win_reg.win32api.RegOpenKeyEx", mock_error):
  723. self.assertRaises(
  724. win32api.error,
  725. win_reg.delete_value,
  726. hive="HKLM",
  727. key=FAKE_KEY,
  728. vname="fake_name",
  729. )
  730. @destructiveTest
  731. def test_delete_value_unicode(self):
  732. """
  733. Test the delete_value function on a unicode value
  734. """
  735. try:
  736. self.assertTrue(
  737. win_reg.set_value(
  738. hive="HKLM", key=FAKE_KEY, vname="fake_unicode", vdata=UNICODE_VALUE
  739. )
  740. )
  741. self.assertTrue(
  742. win_reg.delete_value(hive="HKLM", key=FAKE_KEY, vname="fake_unicode")
  743. )
  744. finally:
  745. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  746. @destructiveTest
  747. def test_delete_value_unicode_vname(self):
  748. """
  749. Test the delete_value function on a unicode vname
  750. """
  751. try:
  752. self.assertTrue(
  753. win_reg.set_value(
  754. hive="HKLM", key=FAKE_KEY, vname=UNICODE_KEY, vdata="junk data"
  755. )
  756. )
  757. self.assertTrue(
  758. win_reg.delete_value(hive="HKLM", key=FAKE_KEY, vname=UNICODE_KEY)
  759. )
  760. finally:
  761. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  762. @destructiveTest
  763. def test_delete_value_unicode_key(self):
  764. """
  765. Test the delete_value function on a unicode key
  766. """
  767. try:
  768. self.assertTrue(
  769. win_reg.set_value(
  770. hive="HKLM",
  771. key="\\".join([FAKE_KEY, UNICODE_KEY]),
  772. vname="fake_name",
  773. vdata="junk data",
  774. )
  775. )
  776. self.assertTrue(
  777. win_reg.delete_value(
  778. hive="HKLM",
  779. key="\\".join([FAKE_KEY, UNICODE_KEY]),
  780. vname="fake_name",
  781. )
  782. )
  783. finally:
  784. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  785. def test_delete_key_recursive_invalid_hive(self):
  786. """
  787. Test the delete_key_recursive function when passing an invalid hive
  788. """
  789. self.assertRaises(
  790. CommandExecutionError,
  791. win_reg.delete_key_recursive,
  792. hive="BADHIVE",
  793. key=FAKE_KEY,
  794. )
  795. def test_delete_key_recursive_key_not_found(self):
  796. """
  797. Test the delete_key_recursive function when the passed key to delete is
  798. not found.
  799. """
  800. self.assertFalse(win_reg.key_exists(hive="HKLM", key=FAKE_KEY))
  801. self.assertFalse(win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY))
  802. def test_delete_key_recursive_too_close(self):
  803. """
  804. Test the delete_key_recursive function when the passed key to delete is
  805. too close to root, such as
  806. """
  807. mock_true = MagicMock(return_value=True)
  808. with patch("salt.utils.win_reg.key_exists", mock_true):
  809. self.assertFalse(win_reg.delete_key_recursive(hive="HKLM", key="FAKE_KEY"))
  810. @destructiveTest
  811. def test_delete_key_recursive(self):
  812. """
  813. Test the delete_key_recursive function
  814. """
  815. try:
  816. self.assertTrue(
  817. win_reg.set_value(
  818. hive="HKLM", key=FAKE_KEY, vname="fake_name", vdata="fake_value"
  819. )
  820. )
  821. expected = {"Deleted": ["\\".join(["HKLM", FAKE_KEY])], "Failed": []}
  822. self.assertDictEqual(
  823. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY), expected
  824. )
  825. finally:
  826. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  827. @destructiveTest
  828. def test_delete_key_recursive_failed_to_open_key(self):
  829. """
  830. Test the delete_key_recursive function on failure to open the key
  831. """
  832. try:
  833. self.assertTrue(
  834. win_reg.set_value(
  835. hive="HKLM", key=FAKE_KEY, vname="fake_name", vdata="fake_value"
  836. )
  837. )
  838. expected = {
  839. "Deleted": [],
  840. "Failed": ["\\".join(["HKLM", FAKE_KEY]) + " Failed to connect to key"],
  841. }
  842. mock_true = MagicMock(return_value=True)
  843. mock_error = MagicMock(
  844. side_effect=[
  845. 1,
  846. win32api.error(3, "RegOpenKeyEx", "Failed to connect to key"),
  847. ]
  848. )
  849. with patch("salt.utils.win_reg.key_exists", mock_true), patch(
  850. "salt.utils.win_reg.win32api.RegOpenKeyEx", mock_error
  851. ):
  852. self.assertDictEqual(
  853. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY), expected
  854. )
  855. finally:
  856. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  857. @destructiveTest
  858. def test_delete_key_recursive_failed_to_delete(self):
  859. """
  860. Test the delete_key_recursive function on failure to delete a key
  861. """
  862. try:
  863. self.assertTrue(
  864. win_reg.set_value(
  865. hive="HKLM", key=FAKE_KEY, vname="fake_name", vdata="fake_value"
  866. )
  867. )
  868. expected = {
  869. "Deleted": [],
  870. "Failed": ["\\".join(["HKLM", FAKE_KEY]) + " Unknown error"],
  871. }
  872. # pylint: disable=undefined-variable
  873. mock_error = MagicMock(side_effect=WindowsError("Unknown error"))
  874. # pylint: enable=undefined-variable
  875. with patch("salt.utils.win_reg.win32api.RegDeleteKey", mock_error):
  876. self.assertDictEqual(
  877. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY), expected
  878. )
  879. finally:
  880. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  881. @destructiveTest
  882. def test_delete_key_recursive_unicode(self):
  883. """
  884. Test the delete_key_recursive function on value within a unicode key
  885. """
  886. try:
  887. self.assertTrue(
  888. win_reg.set_value(
  889. hive="HKLM",
  890. key="\\".join([FAKE_KEY, UNICODE_KEY]),
  891. vname="fake_name",
  892. vdata="fake_value",
  893. )
  894. )
  895. expected = {
  896. "Deleted": ["\\".join(["HKLM", FAKE_KEY, UNICODE_KEY])],
  897. "Failed": [],
  898. }
  899. self.assertDictEqual(
  900. win_reg.delete_key_recursive(
  901. hive="HKLM", key="\\".join([FAKE_KEY, UNICODE_KEY])
  902. ),
  903. expected,
  904. )
  905. finally:
  906. win_reg.delete_key_recursive(hive="HKLM", key=FAKE_KEY)
  907. def test__to_unicode_int(self):
  908. """
  909. Test the ``_to_unicode`` function when it receives an integer value.
  910. Should return a unicode value, which is unicode in PY2 and str in PY3.
  911. """
  912. if six.PY3:
  913. self.assertTrue(isinstance(win_reg._to_unicode(1), str))
  914. else:
  915. # fmt: off
  916. self.assertTrue(
  917. isinstance(
  918. win_reg._to_unicode(1),
  919. unicode, # pylint: disable=incompatible-py3-code,undefined-variable
  920. )
  921. )
  922. # fmt: on