blob: e852c69684ce4aa77ea4967a1a909025a2219762 [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
Fred Drake252af9c2000-06-29 19:42:00 +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)
32 # Create a sub-key
Martin v. Löwisf82d9b52007-09-03 07:43:05 +000033 sub_key = CreateKey(key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +000034 # Give the sub-key some named values
35
36 for value_name, value_data, value_type in test_data:
37 SetValueEx(sub_key, value_name, 0, value_type, value_data)
38
39 # Check we wrote as many items as we thought.
40 nkeys, nvalues, since_mod = QueryInfoKey(key)
41 self.assertEquals(nkeys, 1, "Not the correct number of sub keys")
42 self.assertEquals(nvalues, 1, "Not the correct number of values")
43 nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
44 self.assertEquals(nkeys, 0, "Not the correct number of sub keys")
45 self.assertEquals(nvalues, len(test_data),
46 "Not the correct number of values")
47 # Close this key this way...
48 # (but before we do, copy the key as an integer - this allows
49 # us to test that the key really gets closed).
50 int_sub_key = int(sub_key)
51 CloseKey(sub_key)
52 try:
53 QueryInfoKey(int_sub_key)
54 self.fail("It appears the CloseKey() function does "
55 "not close the actual key!")
56 except EnvironmentError:
57 pass
58 # ... and close that key that way :-)
59 int_key = int(key)
60 key.Close()
61 try:
62 QueryInfoKey(int_key)
63 self.fail("It appears the key.Close() function "
64 "does not close the actual key!")
65 except EnvironmentError:
66 pass
67
Martin v. Löwisf82d9b52007-09-03 07:43:05 +000068 def ReadTestData(self, root_key, subkeystr="sub_key"):
Thomas Woutersed03b412007-08-28 21:37:11 +000069 # Check we can get default value for this key.
70 val = QueryValue(root_key, test_key_name)
71 self.assertEquals(val, "Default value",
72 "Registry didn't give back the correct value")
73
74 key = OpenKey(root_key, test_key_name)
75 # Read the sub-keys
Thomas Hellere83ebd92008-01-24 10:31:31 +000076 with OpenKey(key, subkeystr) as sub_key:
Christian Heimes2380ac72008-01-09 00:17:24 +000077 # Check I can enumerate over the values.
78 index = 0
79 while 1:
80 try:
81 data = EnumValue(sub_key, index)
82 except EnvironmentError:
83 break
84 self.assertEquals(data in test_data, True,
85 "Didn't read back the correct test data")
86 index = index + 1
87 self.assertEquals(index, len(test_data),
88 "Didn't read the correct number of items")
89 # Check I can directly access each item
90 for value_name, value_data, value_type in test_data:
91 read_val, read_typ = QueryValueEx(sub_key, value_name)
92 self.assertEquals(read_val, value_data,
93 "Could not directly read the value")
94 self.assertEquals(read_typ, value_type,
95 "Could not directly read the value")
Thomas Woutersed03b412007-08-28 21:37:11 +000096 sub_key.Close()
97 # Enumerate our main key.
98 read_val = EnumKey(key, 0)
Martin v. Löwisf82d9b52007-09-03 07:43:05 +000099 self.assertEquals(read_val, subkeystr, "Read subkey value wrong")
Thomas Woutersed03b412007-08-28 21:37:11 +0000100 try:
101 EnumKey(key, 1)
102 self.fail("Was able to get a second key when I only have one!")
103 except EnvironmentError:
104 pass
105
106 key.Close()
107
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000108 def DeleteTestData(self, root_key, subkeystr="sub_key"):
Thomas Woutersed03b412007-08-28 21:37:11 +0000109 key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS)
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000110 sub_key = OpenKey(key, subkeystr, 0, KEY_ALL_ACCESS)
Thomas Woutersed03b412007-08-28 21:37:11 +0000111 # It is not necessary to delete the values before deleting
112 # the key (although subkeys must not exist). We delete them
113 # manually just to prove we can :-)
114 for value_name, value_data, value_type in test_data:
115 DeleteValue(sub_key, value_name)
116
117 nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
118 self.assertEquals(nkeys, 0, "subkey not empty before delete")
119 self.assertEquals(nvalues, 0, "subkey not empty before delete")
120 sub_key.Close()
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000121 DeleteKey(key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +0000122
123 try:
124 # Shouldnt be able to delete it twice!
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000125 DeleteKey(key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +0000126 self.fail("Deleting the key twice succeeded")
127 except EnvironmentError:
128 pass
129 key.Close()
130 DeleteKey(root_key, test_key_name)
131 # Opening should now fail!
132 try:
133 key = OpenKey(root_key, test_key_name)
134 self.fail("Could open the non-existent key")
135 except WindowsError: # Use this error name this time
136 pass
137
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000138 def TestAll(self, root_key, subkeystr="sub_key"):
139 self.WriteTestData(root_key, subkeystr)
140 self.ReadTestData(root_key, subkeystr)
141 self.DeleteTestData(root_key, subkeystr)
Thomas Woutersed03b412007-08-28 21:37:11 +0000142
143 def testLocalMachineRegistryWorks(self):
144 self.TestAll(HKEY_CURRENT_USER)
Martin v. Löwisf82d9b52007-09-03 07:43:05 +0000145 self.TestAll(HKEY_CURRENT_USER, "日本-subkey")
Thomas Woutersed03b412007-08-28 21:37:11 +0000146
147 def testConnectRegistryToLocalMachineWorks(self):
148 # perform minimal ConnectRegistry test which just invokes it
149 h = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
150 h.Close()
151
152 def testRemoteMachineRegistryWorks(self):
153 if not self.remote_name:
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000154 return # remote machine name not specified
Thomas Woutersed03b412007-08-28 21:37:11 +0000155 remote_key = ConnectRegistry(self.remote_name, HKEY_CURRENT_USER)
156 self.TestAll(remote_key)
157
Christian Heimes2380ac72008-01-09 00:17:24 +0000158 def testExpandEnvironmentStrings(self):
159 r = ExpandEnvironmentStrings("%windir%\\test")
160 self.assertEqual(type(r), str)
161 self.assertEqual(r, os.environ["windir"] + "\\test")
162
Thomas Woutersed03b412007-08-28 21:37:11 +0000163def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000164 support.run_unittest(WinregTests)
Thomas Woutersed03b412007-08-28 21:37:11 +0000165
166if __name__ == "__main__":
Guido van Rossumde598552000-03-28 20:36:51 +0000167 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000168 WinregTests.remote_name = sys.argv[sys.argv.index("--remote")+1]
169 except (IndexError, ValueError):
170 print("Remote registry calls can be tested using",
171 "'test_winreg.py --remote \\\\machine_name'")
172 WinregTests.remote_name = None
173 test_main()