blob: fd288526dbbbb2e28b79f30fd4fa86d153738650 [file] [log] [blame]
Martin v. Löwisf82d9b52007-09-03 07:43:05 +00001# -*- coding: utf-8 -*-
Guido van Rossumde598552000-03-28 20:36:51 +00002# Test the windows specific win32reg module.
3# Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey
4
Guido van Rossumde598552000-03-28 20:36:51 +00005import os, sys
Thomas Woutersed03b412007-08-28 21:37:11 +00006import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import support
Fredrik Lundhf7850422001-01-17 21:51:36 +00008
R. David Murraya21e4ca2009-03-31 23:16:50 +00009# Do this first so test will be skipped if module doesn't exist
10support.import_module('winreg')
11# Now import everything
12from winreg import *
13
Guido van Rossumde598552000-03-28 20:36:51 +000014test_key_name = "SOFTWARE\\Python Registry Test Key - Delete Me"
15
16test_data = [
17 ("Int Value", 45, REG_DWORD),
Guido van Rossum0a185522003-11-30 22:46:18 +000018 ("String Val", "A string value", REG_SZ),
Guido van Rossumde598552000-03-28 20:36:51 +000019 ("StringExpand", "The path is %path%", REG_EXPAND_SZ),
Guido van Rossumde598552000-03-28 20:36:51 +000020 ("Multi-string", ["Lots", "of", "string", "values"], REG_MULTI_SZ),
Thomas Woutersed03b412007-08-28 21:37:11 +000021 ("Raw Data", b"binary\x00data", REG_BINARY),
Guido van Rossum291481b2003-12-03 15:24:02 +000022 ("Big String", "x"*(2**14-1), REG_SZ),
Guido van Rossuma8c360e2007-07-17 20:50:43 +000023 ("Big Binary", b"x"*(2**14), REG_BINARY),
Martin v. Löwisf82d9b52007-09-03 07:43:05 +000024 # Two and three kanjis, meaning: "Japan" and "Japanese")
25 ("Japanese 日本", "日本語", REG_SZ),
Guido van Rossumde598552000-03-28 20:36:51 +000026]
27
Thomas Woutersed03b412007-08-28 21:37:11 +000028class WinregTests(unittest.TestCase):
Guido van Rossumde598552000-03-28 20:36:51 +000029 remote_name = None
30
Martin v. Löwisb7a51562009-06-07 17:55:17 +000031 def setUp(self):
32 # Make sure that the test key is absent when the test
33 # starts.
34 self.delete_tree(HKEY_CURRENT_USER, test_key_name)
35
36 def delete_tree(self, root, subkey):
37 try:
38 hkey = OpenKey(root, subkey, KEY_ALL_ACCESS)
39 except WindowsError:
40 # subkey does not exist
41 return
42 while True:
43 try:
44 subsubkey = EnumKey(hkey, 0)
45 except WindowsError:
46 # no more subkeys
47 break
48 self.delete_tree(hkey, subsubkey)
49 CloseKey(hkey)
50 DeleteKey(root, subkey)
51
Martin v. Löwisf82d9b52007-09-03 07:43:05 +000052 def WriteTestData(self, root_key, subkeystr="sub_key"):
Thomas Woutersed03b412007-08-28 21:37:11 +000053 # Set the default value for this key.
54 SetValue(root_key, test_key_name, REG_SZ, "Default value")
55 key = CreateKey(root_key, test_key_name)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000056 self.assertTrue(key.handle != 0)
Thomas Woutersed03b412007-08-28 21:37:11 +000057 # Create a sub-key
Martin v. Löwisf82d9b52007-09-03 07:43:05 +000058 sub_key = CreateKey(key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +000059 # Give the sub-key some named values
60
61 for value_name, value_data, value_type in test_data:
62 SetValueEx(sub_key, value_name, 0, value_type, value_data)
63
64 # Check we wrote as many items as we thought.
65 nkeys, nvalues, since_mod = QueryInfoKey(key)
66 self.assertEquals(nkeys, 1, "Not the correct number of sub keys")
67 self.assertEquals(nvalues, 1, "Not the correct number of values")
68 nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
69 self.assertEquals(nkeys, 0, "Not the correct number of sub keys")
70 self.assertEquals(nvalues, len(test_data),
71 "Not the correct number of values")
72 # Close this key this way...
73 # (but before we do, copy the key as an integer - this allows
74 # us to test that the key really gets closed).
75 int_sub_key = int(sub_key)
76 CloseKey(sub_key)
77 try:
78 QueryInfoKey(int_sub_key)
79 self.fail("It appears the CloseKey() function does "
80 "not close the actual key!")
81 except EnvironmentError:
82 pass
83 # ... and close that key that way :-)
84 int_key = int(key)
85 key.Close()
86 try:
87 QueryInfoKey(int_key)
88 self.fail("It appears the key.Close() function "
89 "does not close the actual key!")
90 except EnvironmentError:
91 pass
92
Martin v. Löwisf82d9b52007-09-03 07:43:05 +000093 def ReadTestData(self, root_key, subkeystr="sub_key"):
Thomas Woutersed03b412007-08-28 21:37:11 +000094 # Check we can get default value for this key.
95 val = QueryValue(root_key, test_key_name)
96 self.assertEquals(val, "Default value",
97 "Registry didn't give back the correct value")
98
99 key = OpenKey(root_key, test_key_name)
100 # Read the sub-keys
Thomas Hellere83ebd92008-01-24 10:31:31 +0000101 with OpenKey(key, subkeystr) as sub_key:
Christian Heimes2380ac72008-01-09 00:17:24 +0000102 # Check I can enumerate over the values.
103 index = 0
104 while 1:
105 try:
106 data = EnumValue(sub_key, index)
107 except EnvironmentError:
108 break
109 self.assertEquals(data in test_data, True,
110 "Didn't read back the correct test data")
111 index = index + 1
112 self.assertEquals(index, len(test_data),
113 "Didn't read the correct number of items")
114 # Check I can directly access each item
115 for value_name, value_data, value_type in test_data:
116 read_val, read_typ = QueryValueEx(sub_key, value_name)
117 self.assertEquals(read_val, value_data,
118 "Could not directly read the value")
119 self.assertEquals(read_typ, value_type,
120 "Could not directly read the value")
Thomas Woutersed03b412007-08-28 21:37:11 +0000121 sub_key.Close()
122 # Enumerate our main key.
123 read_val = EnumKey(key, 0)
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000124 self.assertEquals(read_val, subkeystr, "Read subkey value wrong")
Thomas Woutersed03b412007-08-28 21:37:11 +0000125 try:
126 EnumKey(key, 1)
127 self.fail("Was able to get a second key when I only have one!")
128 except EnvironmentError:
129 pass
130
131 key.Close()
132
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000133 def DeleteTestData(self, root_key, subkeystr="sub_key"):
Thomas Woutersed03b412007-08-28 21:37:11 +0000134 key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS)
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000135 sub_key = OpenKey(key, subkeystr, 0, KEY_ALL_ACCESS)
Thomas Woutersed03b412007-08-28 21:37:11 +0000136 # It is not necessary to delete the values before deleting
137 # the key (although subkeys must not exist). We delete them
138 # manually just to prove we can :-)
139 for value_name, value_data, value_type in test_data:
140 DeleteValue(sub_key, value_name)
141
142 nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
143 self.assertEquals(nkeys, 0, "subkey not empty before delete")
144 self.assertEquals(nvalues, 0, "subkey not empty before delete")
145 sub_key.Close()
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000146 DeleteKey(key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +0000147
148 try:
149 # Shouldnt be able to delete it twice!
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000150 DeleteKey(key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +0000151 self.fail("Deleting the key twice succeeded")
152 except EnvironmentError:
153 pass
154 key.Close()
155 DeleteKey(root_key, test_key_name)
156 # Opening should now fail!
157 try:
158 key = OpenKey(root_key, test_key_name)
159 self.fail("Could open the non-existent key")
160 except WindowsError: # Use this error name this time
161 pass
162
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000163 def TestAll(self, root_key, subkeystr="sub_key"):
164 self.WriteTestData(root_key, subkeystr)
165 self.ReadTestData(root_key, subkeystr)
166 self.DeleteTestData(root_key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +0000167
168 def testLocalMachineRegistryWorks(self):
169 self.TestAll(HKEY_CURRENT_USER)
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000170 self.TestAll(HKEY_CURRENT_USER, "日本-subkey")
Thomas Woutersed03b412007-08-28 21:37:11 +0000171
172 def testConnectRegistryToLocalMachineWorks(self):
173 # perform minimal ConnectRegistry test which just invokes it
174 h = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
175 h.Close()
176
177 def testRemoteMachineRegistryWorks(self):
178 if not self.remote_name:
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000179 return # remote machine name not specified
Thomas Woutersed03b412007-08-28 21:37:11 +0000180 remote_key = ConnectRegistry(self.remote_name, HKEY_CURRENT_USER)
181 self.TestAll(remote_key)
182
Christian Heimes2380ac72008-01-09 00:17:24 +0000183 def testExpandEnvironmentStrings(self):
184 r = ExpandEnvironmentStrings("%windir%\\test")
185 self.assertEqual(type(r), str)
186 self.assertEqual(r, os.environ["windir"] + "\\test")
187
Thomas Woutersed03b412007-08-28 21:37:11 +0000188def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000189 support.run_unittest(WinregTests)
Thomas Woutersed03b412007-08-28 21:37:11 +0000190
191if __name__ == "__main__":
Guido van Rossumde598552000-03-28 20:36:51 +0000192 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000193 WinregTests.remote_name = sys.argv[sys.argv.index("--remote")+1]
194 except (IndexError, ValueError):
195 print("Remote registry calls can be tested using",
196 "'test_winreg.py --remote \\\\machine_name'")
197 WinregTests.remote_name = None
198 test_main()