# -*- coding: utf-8 -*- ''' :synopsis: Unit Tests for Windows Registry Module 'module.reg' :platform: Windows :maturity: develop :codeauthor: Damon Atkins versionadded:: 2016.11.0 ''' # Import Python future libs from __future__ import absolute_import from __future__ import unicode_literals # Import Python Libs import sys import time # Import Salt Testing Libs from salttesting import TestCase, skipIf from salttesting.helpers import destructiveTest # Import Salt Libs from salt.modules import reg as win_mod_reg from salt.ext import six try: from salt.ext.six.moves import winreg as _winreg # pylint: disable=import-error,no-name-in-module NO_WINDOWS_MODULES = False except ImportError: NO_WINDOWS_MODULES = True PY2 = sys.version_info[0] == 2 # The following used to make sure we are not # testing already existing data # Note strftime retunrns a str, so we need to make it unicode TIMEINT = int(time.time()) if PY2: TIME_INT_UNICODE = six.text_type(TIMEINT) TIMESTR = time.strftime('%X %x %Z').decode('utf-8') else: TIMESTR = time.strftime('%X %x %Z') TIME_INT_UNICODE = str(TIMEINT) # pylint: disable=R0204 # we do not need to prefix this with u, as we are # using from __future__ import unicode_literals UNICODETEST_WITH_SIGNS = 'Testing Unicode \N{COPYRIGHT SIGN},\N{TRADE MARK SIGN},\N{REGISTERED SIGN} '+TIMESTR UNICODETEST_WITHOUT_SIGNS = 'Testing Unicode'+TIMESTR UNICODE_TEST_KEY = 'UnicodeKey \N{TRADE MARK SIGN} '+TIME_INT_UNICODE UNICODE_TEST_KEY_DEL = 'Delete Me \N{TRADE MARK SIGN} '+TIME_INT_UNICODE @skipIf(NO_WINDOWS_MODULES, 'requires Windows OS to test Windows registry') class RegWinTestCase(TestCase): ''' Test cases for salt.modules.reg ''' @skipIf(not sys.platform.startswith("win"), "requires Windows OS") def test_read_reg_plain(self): ''' Test - Read a registry value from a subkey using Pythen 2 Strings or Pythen 3 Bytes ''' if not PY2: self.skipTest('Invalid for Python Version 2') subkey = b'Software\\Microsoft\\Windows NT\\CurrentVersion' vname = b'PathName' handle = _winreg.OpenKey( _winreg.HKEY_LOCAL_MACHINE, subkey, 0, _winreg.KEY_ALL_ACCESS ) (current_vdata, dummy_current_vtype) = _winreg.QueryValueEx(handle, vname) _winreg.CloseKey(handle) test_vdata = win_mod_reg.read_value(b'HKEY_LOCAL_MACHINE', subkey, vname)[b'vdata'] self.assertEqual( test_vdata, current_vdata) @skipIf(not sys.platform.startswith("win"), "requires Windows OS") def test_read_reg_unicode(self): ''' Test - Read a registry value from a subkey using Pythen 2 Unicode or Pythen 3 Str i.e. Unicode ''' subkey = 'Software\\Microsoft\\Windows NT\\CurrentVersion' vname = 'PathName' handle = _winreg.OpenKey( _winreg.HKEY_LOCAL_MACHINE, subkey, 0, _winreg.KEY_ALL_ACCESS ) (current_vdata, dummy_current_vtype) = _winreg.QueryValueEx(handle, vname) _winreg.CloseKey(handle) test_vdata = win_mod_reg.read_value( 'HKEY_LOCAL_MACHINE', subkey, vname)['vdata'] self.assertEqual(test_vdata, current_vdata) @skipIf(not sys.platform.startswith("win"), "requires Windows OS") def test_list_keys_fail(self): ''' Test - Read list the keys under a subkey which does not exist. ''' subkey = 'ThisIsJunkItDoesNotExistIhope' test_list = win_mod_reg.list_keys('HKEY_LOCAL_MACHINE', subkey) # returns a tuple with first item false, and second item a reason test = isinstance(test_list, tuple) and (not test_list[0]) self.assertTrue(test) @skipIf(not sys.platform.startswith("win"), "requires Windows OS") def test_list_keys(self): ''' Test - Read list the keys under a subkey ''' subkey = 'Software\\Microsoft\\Windows NT\\CurrentVersion' test_list = win_mod_reg.list_keys('HKEY_LOCAL_MACHINE', subkey) test = len(test_list) > 5 # Their should be a lot more than 5 items self.assertTrue(test) @skipIf(not sys.platform.startswith("win"), "requires Windows OS") def test_list_values_fail(self): ''' Test - List the values under a subkey which does not exist. ''' subkey = 'ThisIsJunkItDoesNotExistIhope' test_list = win_mod_reg.list_values('HKEY_LOCAL_MACHINE', subkey) # returns a tuple with first item false, and second item a reason test = isinstance(test_list, tuple) and (not test_list[0]) self.assertTrue(test) @skipIf(not sys.platform.startswith("win"), "requires Windows OS") def test_list_values(self): ''' Test - List the values under a subkey. ''' subkey = r'Software\Microsoft\Windows NT\CurrentVersion' test_list = win_mod_reg.list_values('HKEY_LOCAL_MACHINE', subkey) test = len(test_list) > 5 # There should be a lot more than 5 items self.assertTrue(test) # Not considering this destructive as its writing to a private space @skipIf(not sys.platform.startswith("win"), "requires Windows OS") def test_set_value_unicode(self): ''' Test - set a registry plain text subkey name to a unicode string value ''' vname = 'TestUniccodeString' subkey = 'Software\\SaltStackTest' test1_success = False test2_success = False test1_success = win_mod_reg.set_value( 'HKEY_LOCAL_MACHINE', subkey, vname, UNICODETEST_WITH_SIGNS ) # Now use _winreg direct to see if it worked as expected if test1_success: handle = _winreg.OpenKey( _winreg.HKEY_LOCAL_MACHINE, subkey, 0, _winreg.KEY_ALL_ACCESS ) (current_vdata, dummy_current_vtype) = _winreg.QueryValueEx(handle, vname) _winreg.CloseKey(handle) test2_success = (current_vdata == UNICODETEST_WITH_SIGNS) self.assertTrue(test1_success and test2_success) @skipIf(not sys.platform.startswith("win"), "requires Windows OS") def test_set_value_unicode_key(self): ''' Test - set a registry Unicode subkey name with unicode characters within to a integer ''' test_success = win_mod_reg.set_value( 'HKEY_LOCAL_MACHINE', 'Software\\SaltStackTest', UNICODE_TEST_KEY, TIMEINT, 'REG_DWORD' ) self.assertTrue(test_success) @skipIf(not sys.platform.startswith("win"), "requires Windows OS") def test_del_value(self): ''' Test - Create Directly and Delete with salt a registry value ''' subkey = 'Software\\SaltStackTest' vname = UNICODE_TEST_KEY_DEL vdata = 'I will be deleted' if PY2: handle = _winreg.CreateKeyEx( _winreg.HKEY_LOCAL_MACHINE, subkey.encode('mbcs'), 0, _winreg.KEY_ALL_ACCESS ) _winreg.SetValueEx( handle, vname.encode('mbcs'), 0, _winreg.REG_SZ, vdata.encode('mbcs') ) else: handle = _winreg.CreateKeyEx( _winreg.HKEY_LOCAL_MACHINE, subkey, 0, _winreg.KEY_ALL_ACCESS ) _winreg.SetValueEx(handle, vname, 0, _winreg.REG_SZ, vdata) _winreg.CloseKey(handle) # time.sleep(15) # delays for 15 seconds test_success = win_mod_reg.delete_value( 'HKEY_LOCAL_MACHINE', subkey, vname ) self.assertTrue(test_success) @skipIf(not sys.platform.startswith("win"), "requires Windows OS") def test_del_key_recursive_user(self): ''' Test - Create directly key/value pair and Delete recusivly with salt ''' subkey = 'Software\\SaltStackTest' vname = UNICODE_TEST_KEY_DEL vdata = 'I will be deleted recursive' if PY2: handle = _winreg.CreateKeyEx( _winreg.HKEY_CURRENT_USER, subkey.encode('mbcs'), 0, _winreg.KEY_ALL_ACCESS ) _winreg.SetValueEx( handle, vname.encode('mbcs'), 0, _winreg.REG_SZ, vdata.encode('mbcs') ) else: handle = _winreg.CreateKeyEx( _winreg.HKEY_CURRENT_USER, subkey, 0, _winreg.KEY_ALL_ACCESS ) _winreg.SetValueEx(handle, vname, 0, _winreg.REG_SZ, vdata) _winreg.CloseKey(handle) # time.sleep(15) # delays for 15 seconds so you can run regedit & watch it happen test_success = win_mod_reg.delete_key_recursive('HKEY_CURRENT_USER', subkey) self.assertTrue(test_success) @skipIf(not sys.platform.startswith("win"), "requires Windows OS") @destructiveTest def test_del_key_recursive_machine(self): ''' This is a DESTRUCTIVE TEST it creates a new registry entry. And then destroys the registry entry recusively , however it is completed in its own space within the registry. We mark this as destructiveTest as it has the potential to detroy a machine if salt reg code has a large error in it. ''' subkey = 'Software\\SaltStackTest' vname = UNICODE_TEST_KEY_DEL vdata = 'I will be deleted recursive' if PY2: handle = _winreg.CreateKeyEx( _winreg.HKEY_LOCAL_MACHINE, subkey.encode('mbcs'), 0, _winreg.KEY_ALL_ACCESS ) _winreg.SetValueEx( handle, vname.encode('mbcs'), 0, _winreg.REG_SZ, vdata.encode('mbcs') ) else: handle = _winreg.CreateKeyEx( _winreg.HKEY_LOCAL_MACHINE, subkey, 0, _winreg.KEY_ALL_ACCESS ) _winreg.SetValueEx(handle, vname, 0, _winreg.REG_SZ, vdata) _winreg.CloseKey(handle) # time.sleep(15) # delays for 15 seconds so you can run regedit and watch it happen test_success = win_mod_reg.delete_key_recursive('HKEY_LOCAL_MACHINE', subkey) self.assertTrue(test_success) # pylint: disable=W0511 # TODO: Test other hives, other than HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER if __name__ == '__main__': from integration import run_tests # pylint: disable=C0413 run_tests(RegWinTestCase, needs_daemon=False)