blob: b4ca5827c22dbdedde29d23517452ef92c7cb934 [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
Georg Brandl38feaf02008-05-25 07:45:51 +00005from winreg import *
Guido van Rossumde598552000-03-28 20:36:51 +00006import os, sys
Thomas Woutersed03b412007-08-28 21:37:11 +00007import unittest
Guido van Rossumde598552000-03-28 20:36:51 +00008
Benjamin Petersonee8712c2008-05-20 21:35:26 +00009from test import support
Fredrik Lundhf7850422001-01-17 21:51:36 +000010
Guido van Rossumde598552000-03-28 20:36:51 +000011test_key_name = "SOFTWARE\\Python Registry Test Key - Delete Me"
12
13test_data = [
14 ("Int Value", 45, REG_DWORD),
Guido van Rossum0a185522003-11-30 22:46:18 +000015 ("String Val", "A string value", REG_SZ),
Guido van Rossumde598552000-03-28 20:36:51 +000016 ("StringExpand", "The path is %path%", REG_EXPAND_SZ),
Guido van Rossumde598552000-03-28 20:36:51 +000017 ("Multi-string", ["Lots", "of", "string", "values"], REG_MULTI_SZ),
Thomas Woutersed03b412007-08-28 21:37:11 +000018 ("Raw Data", b"binary\x00data", REG_BINARY),
Guido van Rossum291481b2003-12-03 15:24:02 +000019 ("Big String", "x"*(2**14-1), REG_SZ),
Guido van Rossuma8c360e2007-07-17 20:50:43 +000020 ("Big Binary", b"x"*(2**14), REG_BINARY),
Martin v. Löwisf82d9b52007-09-03 07:43:05 +000021 # Two and three kanjis, meaning: "Japan" and "Japanese")
22 ("Japanese 日本", "日本語", REG_SZ),
Guido van Rossumde598552000-03-28 20:36:51 +000023]
24
Thomas Woutersed03b412007-08-28 21:37:11 +000025class WinregTests(unittest.TestCase):
Guido van Rossumde598552000-03-28 20:36:51 +000026 remote_name = None
27
Martin v. Löwisf82d9b52007-09-03 07:43:05 +000028 def WriteTestData(self, root_key, subkeystr="sub_key"):
Thomas Woutersed03b412007-08-28 21:37:11 +000029 # Set the default value for this key.
30 SetValue(root_key, test_key_name, REG_SZ, "Default value")
31 key = CreateKey(root_key, test_key_name)
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +000032 self.assert_(key.handle != 0)
Thomas Woutersed03b412007-08-28 21:37:11 +000033 # Create a sub-key
Martin v. Löwisf82d9b52007-09-03 07:43:05 +000034 sub_key = CreateKey(key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +000035 # Give the sub-key some named values
36
37 for value_name, value_data, value_type in test_data:
38 SetValueEx(sub_key, value_name, 0, value_type, value_data)
39
40 # Check we wrote as many items as we thought.
41 nkeys, nvalues, since_mod = QueryInfoKey(key)
42 self.assertEquals(nkeys, 1, "Not the correct number of sub keys")
43 self.assertEquals(nvalues, 1, "Not the correct number of values")
44 nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
45 self.assertEquals(nkeys, 0, "Not the correct number of sub keys")
46 self.assertEquals(nvalues, len(test_data),
47 "Not the correct number of values")
48 # Close this key this way...
49 # (but before we do, copy the key as an integer - this allows
50 # us to test that the key really gets closed).
51 int_sub_key = int(sub_key)
52 CloseKey(sub_key)
53 try:
54 QueryInfoKey(int_sub_key)
55 self.fail("It appears the CloseKey() function does "
56 "not close the actual key!")
57 except EnvironmentError:
58 pass
59 # ... and close that key that way :-)
60 int_key = int(key)
61 key.Close()
62 try:
63 QueryInfoKey(int_key)
64 self.fail("It appears the key.Close() function "
65 "does not close the actual key!")
66 except EnvironmentError:
67 pass
68
Martin v. Löwisf82d9b52007-09-03 07:43:05 +000069 def ReadTestData(self, root_key, subkeystr="sub_key"):
Thomas Woutersed03b412007-08-28 21:37:11 +000070 # Check we can get default value for this key.
71 val = QueryValue(root_key, test_key_name)
72 self.assertEquals(val, "Default value",
73 "Registry didn't give back the correct value")
74
75 key = OpenKey(root_key, test_key_name)
76 # Read the sub-keys
Thomas Hellere83ebd92008-01-24 10:31:31 +000077 with OpenKey(key, subkeystr) as sub_key:
Christian Heimes2380ac72008-01-09 00:17:24 +000078 # Check I can enumerate over the values.
79 index = 0
80 while 1:
81 try:
82 data = EnumValue(sub_key, index)
83 except EnvironmentError:
84 break
85 self.assertEquals(data in test_data, True,
86 "Didn't read back the correct test data")
87 index = index + 1
88 self.assertEquals(index, len(test_data),
89 "Didn't read the correct number of items")
90 # Check I can directly access each item
91 for value_name, value_data, value_type in test_data:
92 read_val, read_typ = QueryValueEx(sub_key, value_name)
93 self.assertEquals(read_val, value_data,
94 "Could not directly read the value")
95 self.assertEquals(read_typ, value_type,
96 "Could not directly read the value")
Thomas Woutersed03b412007-08-28 21:37:11 +000097 sub_key.Close()
98 # Enumerate our main key.
99 read_val = EnumKey(key, 0)
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000100 self.assertEquals(read_val, subkeystr, "Read subkey value wrong")
Thomas Woutersed03b412007-08-28 21:37:11 +0000101 try:
102 EnumKey(key, 1)
103 self.fail("Was able to get a second key when I only have one!")
104 except EnvironmentError:
105 pass
106
107 key.Close()
108
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000109 def DeleteTestData(self, root_key, subkeystr="sub_key"):
Thomas Woutersed03b412007-08-28 21:37:11 +0000110 key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS)
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000111 sub_key = OpenKey(key, subkeystr, 0, KEY_ALL_ACCESS)
Thomas Woutersed03b412007-08-28 21:37:11 +0000112 # It is not necessary to delete the values before deleting
113 # the key (although subkeys must not exist). We delete them
114 # manually just to prove we can :-)
115 for value_name, value_data, value_type in test_data:
116 DeleteValue(sub_key, value_name)
117
118 nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
119 self.assertEquals(nkeys, 0, "subkey not empty before delete")
120 self.assertEquals(nvalues, 0, "subkey not empty before delete")
121 sub_key.Close()
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000122 DeleteKey(key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +0000123
124 try:
125 # Shouldnt be able to delete it twice!
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000126 DeleteKey(key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +0000127 self.fail("Deleting the key twice succeeded")
128 except EnvironmentError:
129 pass
130 key.Close()
131 DeleteKey(root_key, test_key_name)
132 # Opening should now fail!
133 try:
134 key = OpenKey(root_key, test_key_name)
135 self.fail("Could open the non-existent key")
136 except WindowsError: # Use this error name this time
137 pass
138
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000139 def TestAll(self, root_key, subkeystr="sub_key"):
140 self.WriteTestData(root_key, subkeystr)
141 self.ReadTestData(root_key, subkeystr)
142 self.DeleteTestData(root_key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +0000143
144 def testLocalMachineRegistryWorks(self):
145 self.TestAll(HKEY_CURRENT_USER)
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000146 self.TestAll(HKEY_CURRENT_USER, "日本-subkey")
Thomas Woutersed03b412007-08-28 21:37:11 +0000147
148 def testConnectRegistryToLocalMachineWorks(self):
149 # perform minimal ConnectRegistry test which just invokes it
150 h = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
151 h.Close()
152
153 def testRemoteMachineRegistryWorks(self):
154 if not self.remote_name:
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000155 return # remote machine name not specified
Thomas Woutersed03b412007-08-28 21:37:11 +0000156 remote_key = ConnectRegistry(self.remote_name, HKEY_CURRENT_USER)
157 self.TestAll(remote_key)
158
Christian Heimes2380ac72008-01-09 00:17:24 +0000159 def testExpandEnvironmentStrings(self):
160 r = ExpandEnvironmentStrings("%windir%\\test")
161 self.assertEqual(type(r), str)
162 self.assertEqual(r, os.environ["windir"] + "\\test")
163
Thomas Woutersed03b412007-08-28 21:37:11 +0000164def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000165 support.run_unittest(WinregTests)
Thomas Woutersed03b412007-08-28 21:37:11 +0000166
167if __name__ == "__main__":
Guido van Rossumde598552000-03-28 20:36:51 +0000168 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000169 WinregTests.remote_name = sys.argv[sys.argv.index("--remote")+1]
170 except (IndexError, ValueError):
171 print("Remote registry calls can be tested using",
172 "'test_winreg.py --remote \\\\machine_name'")
173 WinregTests.remote_name = None
174 test_main()