Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(4)

Delta Between Two Patch Sets: Lib/test/test_winreg.py

Issue 25778: winreg.EnumValue does not truncate strings correctly
Left Patch Set: Created 4 years, 3 months ago
Right Patch Set: Created 4 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | PC/winreg.c » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # Test the windows specific win32reg module. 1 # Test the windows specific win32reg module.
2 # Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey 2 # Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey
3 3
4 import os, sys, errno 4 import os, sys, errno
5 import unittest 5 import unittest
6 from test import test_support 6 from test import support
7 threading = test_support.import_module("threading") 7 threading = support.import_module("threading")
8 from platform import machine 8 from platform import machine
9 9
10 # Do this first so test will be skipped if module doesn't exist 10 # Do this first so test will be skipped if module doesn't exist
11 test_support.import_module('_winreg') 11 support.import_module('winreg', required_on=['win'])
12 # Now import everything 12 # Now import everything
13 from _winreg import * 13 from winreg import *
14 14
15 try: 15 try:
16 REMOTE_NAME = sys.argv[sys.argv.index("--remote")+1] 16 REMOTE_NAME = sys.argv[sys.argv.index("--remote")+1]
17 except (IndexError, ValueError): 17 except (IndexError, ValueError):
18 REMOTE_NAME = None 18 REMOTE_NAME = None
19 19
20 # tuple of (major, minor) 20 # tuple of (major, minor)
21 WIN_VER = sys.getwindowsversion()[:2] 21 WIN_VER = sys.getwindowsversion()[:2]
22 # Some tests should only run on 64-bit architectures where WOW64 will be. 22 # Some tests should only run on 64-bit architectures where WOW64 will be.
23 WIN64_MACHINE = True if machine() == "AMD64" else False 23 WIN64_MACHINE = True if machine() == "AMD64" else False
24 24
25 # Starting with Windows 7 and Windows Server 2008 R2, WOW64 no longer uses 25 # Starting with Windows 7 and Windows Server 2008 R2, WOW64 no longer uses
26 # registry reflection and formerly reflected keys are shared instead. 26 # registry reflection and formerly reflected keys are shared instead.
27 # Windows 7 and Windows Server 2008 R2 are version 6.1. Due to this, some 27 # Windows 7 and Windows Server 2008 R2 are version 6.1. Due to this, some
28 # tests are only valid up until 6.1 28 # tests are only valid up until 6.1
29 HAS_REFLECTION = True if WIN_VER < (6, 1) else False 29 HAS_REFLECTION = True if WIN_VER < (6, 1) else False
30 30
31 # Use a per-process key to prevent concurrent test runs (buildbot!) from 31 # Use a per-process key to prevent concurrent test runs (buildbot!) from
32 # stomping on each other. 32 # stomping on each other.
33 test_key_base = "Python Test Key [%d] - Delete Me" % (os.getpid(),) 33 test_key_base = "Python Test Key [%d] - Delete Me" % (os.getpid(),)
34 test_key_name = "SOFTWARE\\" + test_key_base 34 test_key_name = "SOFTWARE\\" + test_key_base
35 # On OS'es that support reflection we should test with a reflected key 35 # On OS'es that support reflection we should test with a reflected key
36 test_reflect_key_name = "SOFTWARE\\Classes\\" + test_key_base 36 test_reflect_key_name = "SOFTWARE\\Classes\\" + test_key_base
37 37
38 test_data = [ 38 test_data = [
39 ("Int Value", 45, REG_DWORD), 39 ("Int Value", 45, REG_DWORD),
40 ("String Val", "A string value", REG_SZ), 40 ("String Val", "A string value", REG_SZ),
41 ("StringExpand", "The path is %path%", REG_EXPAND_SZ), 41 ("StringExpand", "The path is %path%", REG_EXPAND_SZ),
42 ("Multi-string", ["Lots", "of", "string", "values"], REG_MULTI_SZ), 42 ("Multi-string", ["Lots", "of", "string", "values"], REG_MULTI_SZ),
43 ("Raw Data", ("binary"+chr(0)+"data"), REG_BINARY), 43 ("Raw Data", b"binary\x00data", REG_BINARY),
44 ("Big String", "x"*(2**14-1), REG_SZ), 44 ("Big String", "x"*(2**14-1), REG_SZ),
45 ("Big Binary", "x"*(2**14), REG_BINARY), 45 ("Big Binary", b"x"*(2**14), REG_BINARY),
46 # Two and three kanjis, meaning: "Japan" and "Japanese")
47 ("Japanese 日本", "日本語", REG_SZ),
46 ] 48 ]
47
48 if test_support.have_unicode:
49 test_data += [
50 (unicode("Unicode Val"), unicode("A Unicode value"), REG_SZ,),
51 ("UnicodeExpand", unicode("The path is %path%"), REG_EXPAND_SZ),
52 ("Multi-unicode", [unicode("Lots"), unicode("of"), unicode("unicode"),
53 unicode("values")], REG_MULTI_SZ),
54 ("Multi-mixed", [unicode("Unicode"), unicode("and"), "string",
55 "values"], REG_MULTI_SZ),
56 ]
57 49
58 class BaseWinregTests(unittest.TestCase): 50 class BaseWinregTests(unittest.TestCase):
59 51
60 def setUp(self): 52 def setUp(self):
61 # Make sure that the test key is absent when the test 53 # Make sure that the test key is absent when the test
62 # starts. 54 # starts.
63 self.delete_tree(HKEY_CURRENT_USER, test_key_name) 55 self.delete_tree(HKEY_CURRENT_USER, test_key_name)
64 56
65 def delete_tree(self, root, subkey): 57 def delete_tree(self, root, subkey):
66 try: 58 try:
67 hkey = OpenKey(root, subkey, 0, KEY_ALL_ACCESS) 59 hkey = OpenKey(root, subkey, 0, KEY_ALL_ACCESS)
68 except WindowsError: 60 except OSError:
69 # subkey does not exist 61 # subkey does not exist
70 return 62 return
71 while True: 63 while True:
72 try: 64 try:
73 subsubkey = EnumKey(hkey, 0) 65 subsubkey = EnumKey(hkey, 0)
74 except WindowsError: 66 except OSError:
75 # no more subkeys 67 # no more subkeys
76 break 68 break
77 self.delete_tree(hkey, subsubkey) 69 self.delete_tree(hkey, subsubkey)
78 CloseKey(hkey) 70 CloseKey(hkey)
79 DeleteKey(root, subkey) 71 DeleteKey(root, subkey)
80 72
81 def _write_test_data(self, root_key, CreateKey=CreateKey): 73 def _write_test_data(self, root_key, subkeystr="sub_key",
74 CreateKey=CreateKey):
82 # Set the default value for this key. 75 # Set the default value for this key.
83 SetValue(root_key, test_key_name, REG_SZ, "Default value") 76 SetValue(root_key, test_key_name, REG_SZ, "Default value")
84 key = CreateKey(root_key, test_key_name) 77 key = CreateKey(root_key, test_key_name)
78 self.assertTrue(key.handle != 0)
85 # Create a sub-key 79 # Create a sub-key
86 sub_key = CreateKey(key, "sub_key") 80 sub_key = CreateKey(key, subkeystr)
87 # Give the sub-key some named values 81 # Give the sub-key some named values
88 82
89 for value_name, value_data, value_type in test_data: 83 for value_name, value_data, value_type in test_data:
90 SetValueEx(sub_key, value_name, 0, value_type, value_data) 84 SetValueEx(sub_key, value_name, 0, value_type, value_data)
91 85
92 # Check we wrote as many items as we thought. 86 # Check we wrote as many items as we thought.
93 nkeys, nvalues, since_mod = QueryInfoKey(key) 87 nkeys, nvalues, since_mod = QueryInfoKey(key)
94 self.assertEqual(nkeys, 1, "Not the correct number of sub keys") 88 self.assertEqual(nkeys, 1, "Not the correct number of sub keys")
95 self.assertEqual(nvalues, 1, "Not the correct number of values") 89 self.assertEqual(nvalues, 1, "Not the correct number of values")
96 nkeys, nvalues, since_mod = QueryInfoKey(sub_key) 90 nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
97 self.assertEqual(nkeys, 0, "Not the correct number of sub keys") 91 self.assertEqual(nkeys, 0, "Not the correct number of sub keys")
98 self.assertEqual(nvalues, len(test_data), 92 self.assertEqual(nvalues, len(test_data),
99 "Not the correct number of values") 93 "Not the correct number of values")
100 # Close this key this way... 94 # Close this key this way...
101 # (but before we do, copy the key as an integer - this allows 95 # (but before we do, copy the key as an integer - this allows
102 # us to test that the key really gets closed). 96 # us to test that the key really gets closed).
103 int_sub_key = int(sub_key) 97 int_sub_key = int(sub_key)
104 CloseKey(sub_key) 98 CloseKey(sub_key)
105 try: 99 try:
106 QueryInfoKey(int_sub_key) 100 QueryInfoKey(int_sub_key)
107 self.fail("It appears the CloseKey() function does " 101 self.fail("It appears the CloseKey() function does "
108 "not close the actual key!") 102 "not close the actual key!")
109 except EnvironmentError: 103 except OSError:
110 pass 104 pass
111 # ... and close that key that way :-) 105 # ... and close that key that way :-)
112 int_key = int(key) 106 int_key = int(key)
113 key.Close() 107 key.Close()
114 try: 108 try:
115 QueryInfoKey(int_key) 109 QueryInfoKey(int_key)
116 self.fail("It appears the key.Close() function " 110 self.fail("It appears the key.Close() function "
117 "does not close the actual key!") 111 "does not close the actual key!")
118 except EnvironmentError: 112 except OSError:
119 pass 113 pass
120 114
121 def _read_test_data(self, root_key, OpenKey=OpenKey): 115 def _read_test_data(self, root_key, subkeystr="sub_key", OpenKey=OpenKey):
122 # Check we can get default value for this key. 116 # Check we can get default value for this key.
123 val = QueryValue(root_key, test_key_name) 117 val = QueryValue(root_key, test_key_name)
124 self.assertEqual(val, "Default value", 118 self.assertEqual(val, "Default value",
125 "Registry didn't give back the correct value") 119 "Registry didn't give back the correct value")
126 120
127 key = OpenKey(root_key, test_key_name) 121 key = OpenKey(root_key, test_key_name)
128 # Read the sub-keys 122 # Read the sub-keys
129 with OpenKey(key, "sub_key") as sub_key: 123 with OpenKey(key, subkeystr) as sub_key:
130 # Check I can enumerate over the values. 124 # Check I can enumerate over the values.
131 index = 0 125 index = 0
132 while 1: 126 while 1:
133 try: 127 try:
134 data = EnumValue(sub_key, index) 128 data = EnumValue(sub_key, index)
135 except EnvironmentError: 129 except OSError:
136 break 130 break
137 self.assertIn(data, test_data, 131 self.assertEqual(data in test_data, True,
138 "Didn't read back the correct test data") 132 "Didn't read back the correct test data")
139 index = index + 1 133 index = index + 1
140 self.assertEqual(index, len(test_data), 134 self.assertEqual(index, len(test_data),
141 "Didn't read the correct number of items") 135 "Didn't read the correct number of items")
142 # Check I can directly access each item 136 # Check I can directly access each item
143 for value_name, value_data, value_type in test_data: 137 for value_name, value_data, value_type in test_data:
144 read_val, read_typ = QueryValueEx(sub_key, value_name) 138 read_val, read_typ = QueryValueEx(sub_key, value_name)
145 self.assertEqual(read_val, value_data, 139 self.assertEqual(read_val, value_data,
146 "Could not directly read the value") 140 "Could not directly read the value")
147 self.assertEqual(read_typ, value_type, 141 self.assertEqual(read_typ, value_type,
148 "Could not directly read the value") 142 "Could not directly read the value")
149 sub_key.Close() 143 sub_key.Close()
150 # Enumerate our main key. 144 # Enumerate our main key.
151 read_val = EnumKey(key, 0) 145 read_val = EnumKey(key, 0)
152 self.assertEqual(read_val, "sub_key", "Read subkey value wrong") 146 self.assertEqual(read_val, subkeystr, "Read subkey value wrong")
153 try: 147 try:
154 EnumKey(key, 1) 148 EnumKey(key, 1)
155 self.fail("Was able to get a second key when I only have one!") 149 self.fail("Was able to get a second key when I only have one!")
156 except EnvironmentError: 150 except OSError:
157 pass 151 pass
158 152
159 key.Close() 153 key.Close()
160 154
161 def _delete_test_data(self, root_key): 155 def _delete_test_data(self, root_key, subkeystr="sub_key"):
162 key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS) 156 key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS)
163 sub_key = OpenKey(key, "sub_key", 0, KEY_ALL_ACCESS) 157 sub_key = OpenKey(key, subkeystr, 0, KEY_ALL_ACCESS)
164 # It is not necessary to delete the values before deleting 158 # It is not necessary to delete the values before deleting
165 # the key (although subkeys must not exist). We delete them 159 # the key (although subkeys must not exist). We delete them
166 # manually just to prove we can :-) 160 # manually just to prove we can :-)
167 for value_name, value_data, value_type in test_data: 161 for value_name, value_data, value_type in test_data:
168 DeleteValue(sub_key, value_name) 162 DeleteValue(sub_key, value_name)
169 163
170 nkeys, nvalues, since_mod = QueryInfoKey(sub_key) 164 nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
171 self.assertEqual(nkeys, 0, "subkey not empty before delete") 165 self.assertEqual(nkeys, 0, "subkey not empty before delete")
172 self.assertEqual(nvalues, 0, "subkey not empty before delete") 166 self.assertEqual(nvalues, 0, "subkey not empty before delete")
173 sub_key.Close() 167 sub_key.Close()
174 DeleteKey(key, "sub_key") 168 DeleteKey(key, subkeystr)
175 169
176 try: 170 try:
177 # Shouldnt be able to delete it twice! 171 # Shouldnt be able to delete it twice!
178 DeleteKey(key, "sub_key") 172 DeleteKey(key, subkeystr)
179 self.fail("Deleting the key twice succeeded") 173 self.fail("Deleting the key twice succeeded")
180 except EnvironmentError: 174 except OSError:
181 pass 175 pass
182 key.Close() 176 key.Close()
183 DeleteKey(root_key, test_key_name) 177 DeleteKey(root_key, test_key_name)
184 # Opening should now fail! 178 # Opening should now fail!
185 try: 179 try:
186 key = OpenKey(root_key, test_key_name) 180 key = OpenKey(root_key, test_key_name)
187 self.fail("Could open the non-existent key") 181 self.fail("Could open the non-existent key")
188 except WindowsError: # Use this error name this time 182 except OSError: # Use this error name this time
189 pass 183 pass
190 184
191 def _test_all(self, root_key): 185 def _test_all(self, root_key, subkeystr="sub_key"):
192 self._write_test_data(root_key) 186 self._write_test_data(root_key, subkeystr)
193 self._read_test_data(root_key) 187 self._read_test_data(root_key, subkeystr)
194 self._delete_test_data(root_key) 188 self._delete_test_data(root_key, subkeystr)
189
190 def _test_named_args(self, key, sub_key):
191 with CreateKeyEx(key=key, sub_key=sub_key, reserved=0,
192 access=KEY_ALL_ACCESS) as ckey:
193 self.assertTrue(ckey.handle != 0)
194
195 with OpenKeyEx(key=key, sub_key=sub_key, reserved=0,
196 access=KEY_ALL_ACCESS) as okey:
197 self.assertTrue(okey.handle != 0)
198
195 199
196 class LocalWinregTests(BaseWinregTests): 200 class LocalWinregTests(BaseWinregTests):
197 201
198 def test_registry_works(self): 202 def test_registry_works(self):
199 self._test_all(HKEY_CURRENT_USER) 203 self._test_all(HKEY_CURRENT_USER)
204 self._test_all(HKEY_CURRENT_USER, "日本-subkey")
200 205
201 def test_registry_works_extended_functions(self): 206 def test_registry_works_extended_functions(self):
202 # Substitute the regular CreateKey and OpenKey calls with their 207 # Substitute the regular CreateKey and OpenKey calls with their
203 # extended counterparts. 208 # extended counterparts.
204 # Note: DeleteKeyEx is not used here because it is platform dependent 209 # Note: DeleteKeyEx is not used here because it is platform dependent
205 cke = lambda key, sub_key: CreateKeyEx(key, sub_key, 0, KEY_ALL_ACCESS) 210 cke = lambda key, sub_key: CreateKeyEx(key, sub_key, 0, KEY_ALL_ACCESS)
206 self._write_test_data(HKEY_CURRENT_USER, cke) 211 self._write_test_data(HKEY_CURRENT_USER, CreateKey=cke)
207 212
208 oke = lambda key, sub_key: OpenKeyEx(key, sub_key, 0, KEY_READ) 213 oke = lambda key, sub_key: OpenKeyEx(key, sub_key, 0, KEY_READ)
209 self._read_test_data(HKEY_CURRENT_USER, oke) 214 self._read_test_data(HKEY_CURRENT_USER, OpenKey=oke)
210 215
211 self._delete_test_data(HKEY_CURRENT_USER) 216 self._delete_test_data(HKEY_CURRENT_USER)
217
218 def test_named_arguments(self):
219 self._test_named_args(HKEY_CURRENT_USER, test_key_name)
220 # Use the regular DeleteKey to clean up
221 # DeleteKeyEx takes named args and is tested separately
222 DeleteKey(HKEY_CURRENT_USER, test_key_name)
212 223
213 def test_connect_registry_to_local_machine_works(self): 224 def test_connect_registry_to_local_machine_works(self):
214 # perform minimal ConnectRegistry test which just invokes it 225 # perform minimal ConnectRegistry test which just invokes it
215 h = ConnectRegistry(None, HKEY_LOCAL_MACHINE) 226 h = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
216 self.assertNotEqual(h.handle, 0) 227 self.assertNotEqual(h.handle, 0)
217 h.Close() 228 h.Close()
218 self.assertEqual(h.handle, 0) 229 self.assertEqual(h.handle, 0)
219 230
220 def test_inexistant_remote_registry(self): 231 def test_inexistant_remote_registry(self):
221 connect = lambda: ConnectRegistry("abcdefghijkl", HKEY_CURRENT_USER) 232 connect = lambda: ConnectRegistry("abcdefghijkl", HKEY_CURRENT_USER)
222 self.assertRaises(WindowsError, connect) 233 self.assertRaises(OSError, connect)
223 234
224 def test_expand_environment_strings(self): 235 def testExpandEnvironmentStrings(self):
225 r = ExpandEnvironmentStrings(u"%windir%\\test") 236 r = ExpandEnvironmentStrings("%windir%\\test")
226 self.assertEqual(type(r), unicode) 237 self.assertEqual(type(r), str)
227 self.assertEqual(r, os.environ["windir"] + "\\test") 238 self.assertEqual(r, os.environ["windir"] + "\\test")
228 239
229 def test_context_manager(self): 240 def test_context_manager(self):
230 # ensure that the handle is closed if an exception occurs 241 # ensure that the handle is closed if an exception occurs
231 try: 242 try:
232 with ConnectRegistry(None, HKEY_LOCAL_MACHINE) as h: 243 with ConnectRegistry(None, HKEY_LOCAL_MACHINE) as h:
233 self.assertNotEqual(h.handle, 0) 244 self.assertNotEqual(h.handle, 0)
234 raise WindowsError 245 raise OSError
235 except WindowsError: 246 except OSError:
236 self.assertEqual(h.handle, 0) 247 self.assertEqual(h.handle, 0)
237 248
238 def test_changing_value(self): 249 def test_changing_value(self):
239 # Issue2810: A race condition in 2.6 and 3.1 may cause 250 # Issue2810: A race condition in 2.6 and 3.1 may cause
240 # EnumValue or QueryValue to raise "WindowsError: More data is 251 # EnumValue or QueryValue to raise "WindowsError: More data is
241 # available" 252 # available"
242 done = False 253 done = False
243 254
244 class VeryActiveThread(threading.Thread): 255 class VeryActiveThread(threading.Thread):
245 def run(self): 256 def run(self):
(...skipping 11 matching lines...) Expand all
257 with CreateKey(HKEY_CURRENT_USER, 268 with CreateKey(HKEY_CURRENT_USER,
258 test_key_name+'\\changing_value') as key: 269 test_key_name+'\\changing_value') as key:
259 for _ in range(1000): 270 for _ in range(1000):
260 num_subkeys, num_values, t = QueryInfoKey(key) 271 num_subkeys, num_values, t = QueryInfoKey(key)
261 for i in range(num_values): 272 for i in range(num_values):
262 name = EnumValue(key, i) 273 name = EnumValue(key, i)
263 QueryValue(key, name[0]) 274 QueryValue(key, name[0])
264 finally: 275 finally:
265 done = True 276 done = True
266 thread.join() 277 thread.join()
267 with OpenKey(HKEY_CURRENT_USER, test_key_name, 0, KEY_ALL_ACCESS) as key: 278 DeleteKey(HKEY_CURRENT_USER, test_key_name+'\\changing_value')
268 DeleteKey(key, 'changing_value')
269 DeleteKey(HKEY_CURRENT_USER, test_key_name) 279 DeleteKey(HKEY_CURRENT_USER, test_key_name)
270 280
271 def test_long_key(self): 281 def test_long_key(self):
272 # Issue2810, in 2.6 and 3.1 when the key name was exactly 256 282 # Issue2810, in 2.6 and 3.1 when the key name was exactly 256
273 # characters, EnumKey raised "WindowsError: More data is 283 # characters, EnumKey raised "WindowsError: More data is
274 # available" 284 # available"
275 name = 'x'*256 285 name = 'x'*256
276 try: 286 try:
277 with CreateKey(HKEY_CURRENT_USER, test_key_name) as key: 287 with CreateKey(HKEY_CURRENT_USER, test_key_name) as key:
278 SetValue(key, name, REG_SZ, 'x') 288 SetValue(key, name, REG_SZ, 'x')
279 num_subkeys, num_values, t = QueryInfoKey(key) 289 num_subkeys, num_values, t = QueryInfoKey(key)
280 EnumKey(key, 0) 290 EnumKey(key, 0)
281 finally: 291 finally:
282 with OpenKey(HKEY_CURRENT_USER, test_key_name, 0, KEY_ALL_ACCESS) as key: 292 DeleteKey(HKEY_CURRENT_USER, '\\'.join((test_key_name, name)))
283 DeleteKey(key, name)
284 DeleteKey(HKEY_CURRENT_USER, test_key_name) 293 DeleteKey(HKEY_CURRENT_USER, test_key_name)
285 294
286 def test_dynamic_key(self): 295 def test_dynamic_key(self):
287 # Issue2810, when the value is dynamically generated, these 296 # Issue2810, when the value is dynamically generated, these
288 # raise "WindowsError: More data is available" in 2.6 and 3.1 297 # raise "WindowsError: More data is available" in 2.6 and 3.1
289 try: 298 try:
290 EnumValue(HKEY_PERFORMANCE_DATA, 0) 299 EnumValue(HKEY_PERFORMANCE_DATA, 0)
291 except OSError as e: 300 except OSError as e:
292 if e.errno in (errno.EPERM, errno.EACCES): 301 if e.errno in (errno.EPERM, errno.EACCES):
293 self.skipTest("access denied to registry key " 302 self.skipTest("access denied to registry key "
294 "(are you running in a non-interactive session?)") 303 "(are you running in a non-interactive session?)")
295 raise 304 raise
296 QueryValueEx(HKEY_PERFORMANCE_DATA, None) 305 QueryValueEx(HKEY_PERFORMANCE_DATA, "")
297 306
298 # Reflection requires XP x64/Vista at a minimum. XP doesn't have this stuff 307 # Reflection requires XP x64/Vista at a minimum. XP doesn't have this stuff
299 # or DeleteKeyEx so make sure their use raises NotImplementedError 308 # or DeleteKeyEx so make sure their use raises NotImplementedError
300 @unittest.skipUnless(WIN_VER < (5, 2), "Requires Windows XP") 309 @unittest.skipUnless(WIN_VER < (5, 2), "Requires Windows XP")
301 def test_reflection_unsupported(self): 310 def test_reflection_unsupported(self):
302 try: 311 try:
303 with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: 312 with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck:
304 self.assertNotEqual(ck.handle, 0) 313 self.assertNotEqual(ck.handle, 0)
305 314
306 key = OpenKey(HKEY_CURRENT_USER, test_key_name) 315 key = OpenKey(HKEY_CURRENT_USER, test_key_name)
(...skipping 15 matching lines...) Expand all
322 # Py2Reg, which gets called by SetValueEx, was using PyLong_AsLong, 331 # Py2Reg, which gets called by SetValueEx, was using PyLong_AsLong,
323 # thus raising OverflowError. The implementation now uses 332 # thus raising OverflowError. The implementation now uses
324 # PyLong_AsUnsignedLong to match DWORD's size. 333 # PyLong_AsUnsignedLong to match DWORD's size.
325 try: 334 try:
326 with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: 335 with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck:
327 self.assertNotEqual(ck.handle, 0) 336 self.assertNotEqual(ck.handle, 0)
328 SetValueEx(ck, "test_name", None, REG_DWORD, 0x80000000) 337 SetValueEx(ck, "test_name", None, REG_DWORD, 0x80000000)
329 finally: 338 finally:
330 DeleteKey(HKEY_CURRENT_USER, test_key_name) 339 DeleteKey(HKEY_CURRENT_USER, test_key_name)
331 340
332 def test_setvalueex_with_memoryview(self):
333 try:
334 with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck:
335 self.assertNotEqual(ck.handle, 0)
336 with self.assertRaises(TypeError):
337 SetValueEx(ck, "test_name", None, REG_BINARY, memoryview('va l'))
338 finally:
339 DeleteKey(HKEY_CURRENT_USER, test_key_name)
340
341 def test_queryvalueex_return_value(self): 341 def test_queryvalueex_return_value(self):
342 # Test for Issue #16759, return unsigned int from QueryValueEx. 342 # Test for Issue #16759, return unsigned int from QueryValueEx.
343 # Reg2Py, which gets called by QueryValueEx, was returning a value 343 # Reg2Py, which gets called by QueryValueEx, was returning a value
344 # generated by PyLong_FromLong. The implementation now uses 344 # generated by PyLong_FromLong. The implementation now uses
345 # PyLong_FromUnsignedLong to match DWORD's size. 345 # PyLong_FromUnsignedLong to match DWORD's size.
346 try: 346 try:
347 with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: 347 with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck:
348 self.assertNotEqual(ck.handle, 0) 348 self.assertNotEqual(ck.handle, 0)
349 test_val = 0x80000000 349 test_val = 0x80000000
350 SetValueEx(ck, "test_name", None, REG_DWORD, test_val) 350 SetValueEx(ck, "test_name", None, REG_DWORD, test_val)
(...skipping 18 matching lines...) Expand all
369 369
370 def test_read_string_containing_null(self): 370 def test_read_string_containing_null(self):
371 # Test for issue 25778: REG_SZ should not contain null characters 371 # Test for issue 25778: REG_SZ should not contain null characters
372 try: 372 try:
373 with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: 373 with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck:
374 self.assertNotEqual(ck.handle, 0) 374 self.assertNotEqual(ck.handle, 0)
375 test_val = "A string\x00 with a null" 375 test_val = "A string\x00 with a null"
376 SetValueEx(ck, "test_name", 0, REG_SZ, test_val) 376 SetValueEx(ck, "test_name", 0, REG_SZ, test_val)
377 ret_val, ret_type = QueryValueEx(ck, "test_name") 377 ret_val, ret_type = QueryValueEx(ck, "test_name")
378 self.assertEqual(ret_type, REG_SZ) 378 self.assertEqual(ret_type, REG_SZ)
379 self.assertEqual(ret_val, u"A string") 379 self.assertEqual(ret_val, "A string")
380 finally: 380 finally:
381 DeleteKey(HKEY_CURRENT_USER, test_key_name) 381 DeleteKey(HKEY_CURRENT_USER, test_key_name)
382 382
383 383
384 @unittest.skipUnless(REMOTE_NAME, "Skipping remote registry tests") 384 @unittest.skipUnless(REMOTE_NAME, "Skipping remote registry tests")
385 class RemoteWinregTests(BaseWinregTests): 385 class RemoteWinregTests(BaseWinregTests):
386 386
387 def test_remote_registry_works(self): 387 def test_remote_registry_works(self):
388 remote_key = ConnectRegistry(REMOTE_NAME, HKEY_CURRENT_USER) 388 remote_key = ConnectRegistry(REMOTE_NAME, HKEY_CURRENT_USER)
389 self._test_all(remote_key) 389 self._test_all(remote_key)
390 390
391 391
392 @unittest.skipUnless(WIN64_MACHINE, "x64 specific registry tests") 392 @unittest.skipUnless(WIN64_MACHINE, "x64 specific registry tests")
393 class Win64WinregTests(BaseWinregTests): 393 class Win64WinregTests(BaseWinregTests):
394
395 def test_named_arguments(self):
396 self._test_named_args(HKEY_CURRENT_USER, test_key_name)
397 # Clean up and also exercise the named arguments
398 DeleteKeyEx(key=HKEY_CURRENT_USER, sub_key=test_key_name,
399 access=KEY_ALL_ACCESS, reserved=0)
394 400
395 def test_reflection_functions(self): 401 def test_reflection_functions(self):
396 # Test that we can call the query, enable, and disable functions 402 # Test that we can call the query, enable, and disable functions
397 # on a key which isn't on the reflection list with no consequences. 403 # on a key which isn't on the reflection list with no consequences.
398 with OpenKey(HKEY_LOCAL_MACHINE, "Software") as key: 404 with OpenKey(HKEY_LOCAL_MACHINE, "Software") as key:
399 # HKLM\Software is redirected but not reflected in all OSes 405 # HKLM\Software is redirected but not reflected in all OSes
400 self.assertTrue(QueryReflectionKey(key)) 406 self.assertTrue(QueryReflectionKey(key))
401 self.assertEqual(None, EnableReflectionKey(key)) 407 self.assertIsNone(EnableReflectionKey(key))
402 self.assertEqual(None, DisableReflectionKey(key)) 408 self.assertIsNone(DisableReflectionKey(key))
403 self.assertTrue(QueryReflectionKey(key)) 409 self.assertTrue(QueryReflectionKey(key))
404 410
405 @unittest.skipUnless(HAS_REFLECTION, "OS doesn't support reflection") 411 @unittest.skipUnless(HAS_REFLECTION, "OS doesn't support reflection")
406 def test_reflection(self): 412 def test_reflection(self):
407 # Test that we can create, open, and delete keys in the 32-bit 413 # Test that we can create, open, and delete keys in the 32-bit
408 # area. Because we are doing this in a key which gets reflected, 414 # area. Because we are doing this in a key which gets reflected,
409 # test the differences of 32 and 64-bit keys before and after the 415 # test the differences of 32 and 64-bit keys before and after the
410 # reflection occurs (ie. when the created key is closed). 416 # reflection occurs (ie. when the created key is closed).
411 try: 417 try:
412 with CreateKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, 0, 418 with CreateKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, 0,
413 KEY_ALL_ACCESS | KEY_WOW64_32KEY) as created_key: 419 KEY_ALL_ACCESS | KEY_WOW64_32KEY) as created_key:
414 self.assertNotEqual(created_key.handle, 0) 420 self.assertNotEqual(created_key.handle, 0)
415 421
416 # The key should now be available in the 32-bit area 422 # The key should now be available in the 32-bit area
417 with OpenKey(HKEY_CURRENT_USER, test_reflect_key_name, 0, 423 with OpenKey(HKEY_CURRENT_USER, test_reflect_key_name, 0,
418 KEY_ALL_ACCESS | KEY_WOW64_32KEY) as key: 424 KEY_ALL_ACCESS | KEY_WOW64_32KEY) as key:
419 self.assertNotEqual(key.handle, 0) 425 self.assertNotEqual(key.handle, 0)
420 426
421 # Write a value to what currently is only in the 32-bit area 427 # Write a value to what currently is only in the 32-bit area
422 SetValueEx(created_key, "", 0, REG_SZ, "32KEY") 428 SetValueEx(created_key, "", 0, REG_SZ, "32KEY")
423 429
424 # The key is not reflected until created_key is closed. 430 # The key is not reflected until created_key is closed.
425 # The 64-bit version of the key should not be available yet. 431 # The 64-bit version of the key should not be available yet.
426 open_fail = lambda: OpenKey(HKEY_CURRENT_USER, 432 open_fail = lambda: OpenKey(HKEY_CURRENT_USER,
427 test_reflect_key_name, 0, 433 test_reflect_key_name, 0,
428 KEY_READ | KEY_WOW64_64KEY) 434 KEY_READ | KEY_WOW64_64KEY)
429 self.assertRaises(WindowsError, open_fail) 435 self.assertRaises(OSError, open_fail)
430 436
431 # Now explicitly open the 64-bit version of the key 437 # Now explicitly open the 64-bit version of the key
432 with OpenKey(HKEY_CURRENT_USER, test_reflect_key_name, 0, 438 with OpenKey(HKEY_CURRENT_USER, test_reflect_key_name, 0,
433 KEY_ALL_ACCESS | KEY_WOW64_64KEY) as key: 439 KEY_ALL_ACCESS | KEY_WOW64_64KEY) as key:
434 self.assertNotEqual(key.handle, 0) 440 self.assertNotEqual(key.handle, 0)
435 # Make sure the original value we set is there 441 # Make sure the original value we set is there
436 self.assertEqual("32KEY", QueryValue(key, "")) 442 self.assertEqual("32KEY", QueryValue(key, ""))
437 # Set a new value, which will get reflected to 32-bit 443 # Set a new value, which will get reflected to 32-bit
438 SetValueEx(key, "", 0, REG_SZ, "64KEY") 444 SetValueEx(key, "", 0, REG_SZ, "64KEY")
439 445
(...skipping 19 matching lines...) Expand all
459 self.assertFalse(disabled) 465 self.assertFalse(disabled)
460 466
461 DisableReflectionKey(created_key) 467 DisableReflectionKey(created_key)
462 self.assertTrue(QueryReflectionKey(created_key)) 468 self.assertTrue(QueryReflectionKey(created_key))
463 469
464 # The key is now closed and would normally be reflected to the 470 # The key is now closed and would normally be reflected to the
465 # 64-bit area, but let's make sure that didn't happen. 471 # 64-bit area, but let's make sure that didn't happen.
466 open_fail = lambda: OpenKeyEx(HKEY_CURRENT_USER, 472 open_fail = lambda: OpenKeyEx(HKEY_CURRENT_USER,
467 test_reflect_key_name, 0, 473 test_reflect_key_name, 0,
468 KEY_READ | KEY_WOW64_64KEY) 474 KEY_READ | KEY_WOW64_64KEY)
469 self.assertRaises(WindowsError, open_fail) 475 self.assertRaises(OSError, open_fail)
470 476
471 # Make sure the 32-bit key is actually there 477 # Make sure the 32-bit key is actually there
472 with OpenKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, 0, 478 with OpenKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, 0,
473 KEY_READ | KEY_WOW64_32KEY) as key: 479 KEY_READ | KEY_WOW64_32KEY) as key:
474 self.assertNotEqual(key.handle, 0) 480 self.assertNotEqual(key.handle, 0)
475 finally: 481 finally:
476 DeleteKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, 482 DeleteKeyEx(HKEY_CURRENT_USER, test_reflect_key_name,
477 KEY_WOW64_32KEY, 0) 483 KEY_WOW64_32KEY, 0)
478 484
479 def test_exception_numbers(self): 485 def test_exception_numbers(self):
480 with self.assertRaises(WindowsError) as ctx: 486 with self.assertRaises(FileNotFoundError) as ctx:
481 QueryValue(HKEY_CLASSES_ROOT, 'some_value_that_does_not_exist') 487 QueryValue(HKEY_CLASSES_ROOT, 'some_value_that_does_not_exist')
482 488
483 self.assertEqual(ctx.exception.errno, 2)
484
485 def test_main(): 489 def test_main():
486 test_support.run_unittest(LocalWinregTests, RemoteWinregTests, 490 support.run_unittest(LocalWinregTests, RemoteWinregTests,
487 Win64WinregTests) 491 Win64WinregTests)
488 492
489 if __name__ == "__main__": 493 if __name__ == "__main__":
490 if not REMOTE_NAME: 494 if not REMOTE_NAME:
491 print "Remote registry calls can be tested using", 495 print("Remote registry calls can be tested using",
492 print "'test_winreg.py --remote \\\\machine_name'" 496 "'test_winreg.py --remote \\\\machine_name'")
493 test_main() 497 test_main()
LEFTRIGHT
« no previous file | PC/winreg.c » ('j') | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+