Additional tests

Adds additional tests for unicode scenarios
Fixes an issue with reg.py when deleting unicode keys
Puts the destructive tests in a try/except block so the delete occurs no
matter what
Uses a randomly generated key name for testing
This commit is contained in:
twangboy 2018-03-22 15:59:46 -06:00
parent fc9ecd75e2
commit 0de54ed953
No known key found for this signature in database
GPG key ID: 93FF3BDEB278C9EB
3 changed files with 204 additions and 413 deletions

View file

@ -624,7 +624,7 @@ def delete_key_recursive(hive, key, use_32bit_registry=False):
while True:
try:
subkey = win32api.RegEnumKey(_key, i)
yield subkey
yield _to_mbcs(subkey)
i += 1
except Exception: # pylint: disable=E0602
break
@ -635,7 +635,7 @@ def delete_key_recursive(hive, key, use_32bit_registry=False):
'''
_key = win32api.RegOpenKeyEx(_hkey, _keypath, 0, _access_mask)
for subkeyname in _subkeys(_key):
subkeypath = r'{0}\{1}'.format(_keypath, subkeyname)
subkeypath = '{0}\\{1}'.format(_keypath, subkeyname)
_ret = _traverse_registry_tree(_hkey, subkeypath, _ret, access_mask)
_ret.append(subkeypath)
return _ret

View file

@ -1,301 +0,0 @@
# -*- coding: utf-8 -*-
'''
:synopsis: Unit Tests for Windows Registry Module 'module.reg'
:platform: Windows
:maturity: develop
:codeauthor: Damon Atkins <https://github.com/damon-atkins>
versionadded:: 2016.11.0
'''
# Import Python future libs
from __future__ import absolute_import, print_function, unicode_literals
# Import Python Libs
import sys
import time
# Import Salt Testing Libs
from tests.support.unit import TestCase, skipIf
from tests.support.helpers import destructiveTest
# Import Salt Libs
import salt.modules.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 returns 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

View file

@ -4,7 +4,7 @@
from __future__ import absolute_import, unicode_literals, print_function
# Import Salt Testing Libs
from tests.support.helpers import destructiveTest
from tests.support.helpers import destructiveTest, generate_random_name
from tests.support.mock import NO_MOCK, NO_MOCK_REASON, patch
from tests.support.unit import TestCase, skipIf
@ -12,6 +12,11 @@ from tests.support.unit import TestCase, skipIf
import salt.utils.platform
import salt.utils.win_reg as win_reg
UNICODE_KEY = 'Unicode Key \N{TRADE MARK SIGN}'
UNICODE_VALUE = 'Unicode Value ' \
'\N{COPYRIGHT SIGN},\N{TRADE MARK SIGN},\N{REGISTERED SIGN}'
FAKE_KEY = 'SOFTWARE\\{0}'.format(generate_random_name('SaltTesting-'))
@skipIf(NO_MOCK, NO_MOCK_REASON)
@skipIf(not salt.utils.platform.is_windows(), 'System is not Windows')
@ -52,7 +57,7 @@ class WinFunctionsTestCase(TestCase):
self.assertEqual(
win_reg.key_exists(
hive='HKLM',
key='SOFTWARE\\Salt\\fake_key'
key=FAKE_KEY
),
False
)
@ -73,11 +78,12 @@ class WinFunctionsTestCase(TestCase):
'''
Test the list_keys function using a non existing registry key
'''
expected = (False, 'Cannot find key: HKLM\\SOFTWARE\\Salt\\fake_key')
expected = (False, 'Cannot find key: HKLM\\{0}'.format(FAKE_KEY))
self.assertEqual(
win_reg.list_keys(
hive='HKLM',
key='SOFTWARE\\Salt\\fake_key'),
key=FAKE_KEY
),
expected
)
@ -98,11 +104,11 @@ class WinFunctionsTestCase(TestCase):
'''
Test the list_values function using a non existing registry key
'''
expected = (False, 'Cannot find key: HKLM\\SOFTWARE\\Salt\\fake_key')
expected = (False, 'Cannot find key: HKLM\\{0}'.format(FAKE_KEY))
self.assertEqual(
win_reg.list_values(
hive='HKLM',
key='SOFTWARE\\Salt\\fake_key'
key=FAKE_KEY
),
expected
)
@ -120,7 +126,8 @@ class WinFunctionsTestCase(TestCase):
def test_read_value_default(self):
'''
Test the read_value function reading the default value
Test the read_value function reading the default value using a well
known registry key
'''
ret = win_reg.read_value(
hive='HKLM',
@ -154,17 +161,17 @@ class WinFunctionsTestCase(TestCase):
Test the read_value function using a non existing registry key
'''
expected = {
'comment': 'Cannot find key: HKLM\\SOFTWARE\\Salt\\fake_key',
'comment': 'Cannot find key: HKLM\\{0}'.format(FAKE_KEY),
'vdata': None,
'vname': 'fake_name',
'success': False,
'hive': 'HKLM',
'key': 'SOFTWARE\\Salt\\fake_key'
'key': FAKE_KEY
}
self.assertEqual(
win_reg.read_value(
hive='HKLM',
key='SOFTWARE\\Salt\\fake_key',
key=FAKE_KEY,
vname='fake_name'
),
expected
@ -175,121 +182,154 @@ class WinFunctionsTestCase(TestCase):
'''
Test the set_value function
'''
self.assertTrue(
win_reg.set_value(
hive='HKLM',
key='SOFTWARE\\Salt\\Test\\',
vname='fake_name',
vdata='fake_data'
try:
self.assertTrue(
win_reg.set_value(
hive='HKLM',
key=FAKE_KEY,
vname='fake_name',
vdata='fake_data'
)
)
)
expected = {
'hive': 'HKLM',
'key': 'SOFTWARE\\Salt\\Test\\',
'success': True,
'vdata': 'fake_data',
'vname': 'fake_name',
'vtype': 'REG_SZ'
}
self.assertEqual(
win_reg.read_value(
hive='HKLM',
key='SOFTWARE\\Salt\\Test\\',
vname='fake_name'
),
expected
)
expected = {
'Deleted': [
'HKLM\\SOFTWARE\\Salt\\Test',
'HKLM\\SOFTWARE\\Salt'
],
'Failed': []
}
self.assertEqual(
win_reg.delete_key_recursive(
hive='HKLM',
key='SOFTWARE\\Salt'
),
expected
)
expected = {
'hive': 'HKLM',
'key': FAKE_KEY,
'success': True,
'vdata': 'fake_data',
'vname': 'fake_name',
'vtype': 'REG_SZ'
}
self.assertEqual(
win_reg.read_value(
hive='HKLM',
key=FAKE_KEY,
vname='fake_name'
),
expected
)
finally:
win_reg.delete_key_recursive(hive='HKLM', key=FAKE_KEY)
@destructiveTest
def test_set_value_default(self):
'''
Test the set_value function on the default value
'''
self.assertTrue(
win_reg.set_value(
hive='HKLM',
key='SOFTWARE\\Salt\\Test\\',
vdata='fake_default_data'
try:
self.assertTrue(
win_reg.set_value(
hive='HKLM',
key=FAKE_KEY,
vdata='fake_default_data'
)
)
)
expected = {
'hive': 'HKLM',
'key': 'SOFTWARE\\Salt\\Test\\',
'success': True,
'vdata': 'fake_default_data',
'vname': '(Default)',
'vtype': 'REG_SZ'
}
self.assertEqual(
win_reg.read_value(
hive='HKLM',
key='SOFTWARE\\Salt\\Test\\',
),
expected
)
expected = {
'Deleted': [
'HKLM\\SOFTWARE\\Salt\\Test',
'HKLM\\SOFTWARE\\Salt'
],
'Failed': []
}
self.assertEqual(
win_reg.delete_key_recursive(
hive='HKLM',
key='SOFTWARE\\Salt'
),
expected
)
expected = {
'hive': 'HKLM',
'key': FAKE_KEY,
'success': True,
'vdata': 'fake_default_data',
'vname': '(Default)',
'vtype': 'REG_SZ'
}
self.assertEqual(
win_reg.read_value(
hive='HKLM',
key=FAKE_KEY,
),
expected
)
finally:
win_reg.delete_key_recursive(hive='HKLM', key=FAKE_KEY)
@destructiveTest
def test_set_value_unicode_key(self):
'''
Test the set_value function on a unicode key
'''
try:
self.assertTrue(
win_reg.set_value(
hive='HKLM',
key='{0}\\{1}'.format(FAKE_KEY, UNICODE_KEY),
vname='fake_name',
vdata='fake_value'
)
)
expected = {
'hive': 'HKLM',
'key': '{0}\\{1}'.format(FAKE_KEY, UNICODE_KEY),
'success': True,
'vdata': 'fake_value',
'vname': 'fake_name',
'vtype': 'REG_SZ'
}
self.assertEqual(
win_reg.read_value(
hive='HKLM',
key='{0}\\{1}'.format(FAKE_KEY, UNICODE_KEY),
vname='fake_name'
),
expected
)
finally:
win_reg.delete_key_recursive(hive='HKLM', key=FAKE_KEY)
@destructiveTest
def test_set_value_unicode_value(self):
'''
Test the set_value function on a unicode value
'''
try:
self.assertTrue(
win_reg.set_value(
hive='HKLM',
key=FAKE_KEY,
vname='fake_unicode',
vdata=UNICODE_VALUE
)
)
expected = {
'hive': 'HKLM',
'key': FAKE_KEY,
'success': True,
'vdata': UNICODE_VALUE,
'vname': 'fake_unicode',
'vtype': 'REG_SZ'
}
self.assertEqual(
win_reg.read_value(
hive='HKLM',
key=FAKE_KEY,
vname='fake_unicode'
),
expected
)
finally:
win_reg.delete_key_recursive(hive='HKLM', key=FAKE_KEY)
@destructiveTest
def test_delete_value(self):
'''
Test the delete_value function
'''
self.assertTrue(
win_reg.set_value(
hive='HKLM',
key='SOFTWARE\\Salt\\Test\\',
vname='fake_name',
vdata='fake_data'
try:
self.assertTrue(
win_reg.set_value(
hive='HKLM',
key=FAKE_KEY,
vname='fake_name',
vdata='fake_data'
)
)
)
self.assertTrue(
win_reg.delete_value(
hive='HKLM',
key='SOFTWARE\\Salt\\Test\\',
vname='fake_name'
self.assertTrue(
win_reg.delete_value(
hive='HKLM',
key=FAKE_KEY,
vname='fake_name'
)
)
)
expected = {
'Deleted': [
'HKLM\\SOFTWARE\\Salt\\Test',
'HKLM\\SOFTWARE\\Salt'
],
'Failed': []
}
self.assertEqual(
win_reg.delete_key_recursive(
hive='HKLM',
key='SOFTWARE\\Salt'
),
expected
)
finally:
win_reg.delete_key_recursive(hive='HKLM', key=FAKE_KEY)
def test_delete_value_non_existing(self):
'''
@ -298,8 +338,60 @@ class WinFunctionsTestCase(TestCase):
self.assertEqual(
win_reg.delete_value(
hive='HKLM',
key='SOFTWARE\\Salt\\Test\\',
key=FAKE_KEY,
vname='fake_name'
),
None
)
@destructiveTest
def test_delete_value_unicode(self):
'''
Test the delete_value function on a unicode value
'''
try:
self.assertTrue(
win_reg.set_value(
hive='HKLM',
key=FAKE_KEY,
vname='fake_unicode',
vdata=UNICODE_VALUE
)
)
self.assertTrue(
win_reg.delete_value(
hive='HKLM',
key=FAKE_KEY,
vname='fake_unicode'
)
)
finally:
win_reg.delete_key_recursive(hive='HKLM', key=FAKE_KEY)
@destructiveTest
def test_delete_key_unicode(self):
'''
Test the delete_value function on value within a unicode key
'''
try:
self.assertTrue(
win_reg.set_value(
hive='HKLM',
key='{0}\\{1}'.format(FAKE_KEY, UNICODE_KEY),
vname='fake_name',
vdata='fake_value'
)
)
expected = {
'Deleted': ['HKLM\\{0}\\{1}\\'.format(FAKE_KEY, UNICODE_KEY)],
'Failed': []
}
self.assertEqual(
win_reg.delete_key_recursive(
hive='HKLM',
key='{0}\\{1}\\'.format(FAKE_KEY, UNICODE_KEY),
),
expectee
)
finally:
win_reg.delete_key_recursive(hive='HKLM', key=FAKE_KEY)