aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-02-28 18:38:46 -0600
committerSean Hall <r.sean.hall@gmail.com>2022-03-01 11:37:00 -0600
commit7e61f48f6be0849cb0c0da796ec77603c14532e5 (patch)
tree154019fc14c82f62a2480023c92775ccf2995a76
parent815b407c1f370dd71efc21248b49e63519a57cb4 (diff)
downloadwix-7e61f48f6be0849cb0c0da796ec77603c14532e5.tar.gz
wix-7e61f48f6be0849cb0c0da796ec77603c14532e5.tar.bz2
wix-7e61f48f6be0849cb0c0da796ec77603c14532e5.zip
Factor out TestRegistryFixture so other tests can mock regutil API's.
-rw-r--r--src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj2
-rw-r--r--src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj.filters16
-rw-r--r--src/burn/test/BurnUnitTest/RegistrationTest.cpp375
-rw-r--r--src/burn/test/BurnUnitTest/TestRegistryFixture.cpp184
-rw-r--r--src/burn/test/BurnUnitTest/TestRegistryFixture.h30
-rw-r--r--src/burn/test/BurnUnitTest/precomp.h1
6 files changed, 352 insertions, 256 deletions
diff --git a/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj b/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj
index 2d141451..36903239 100644
--- a/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj
+++ b/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj
@@ -57,6 +57,7 @@
57 </ClCompile> 57 </ClCompile>
58 <ClCompile Include="RegistrationTest.cpp" /> 58 <ClCompile Include="RegistrationTest.cpp" />
59 <ClCompile Include="SearchTest.cpp" /> 59 <ClCompile Include="SearchTest.cpp" />
60 <ClCompile Include="TestRegistryFixture.cpp" />
60 <ClCompile Include="VariableHelpers.cpp" /> 61 <ClCompile Include="VariableHelpers.cpp" />
61 <ClCompile Include="VariableTest.cpp" /> 62 <ClCompile Include="VariableTest.cpp" />
62 <ClCompile Include="VariantTest.cpp" /> 63 <ClCompile Include="VariantTest.cpp" />
@@ -67,6 +68,7 @@
67 <ClInclude Include="BurnUnitTest.h" /> 68 <ClInclude Include="BurnUnitTest.h" />
68 <ClInclude Include="ManifestHelpers.h" /> 69 <ClInclude Include="ManifestHelpers.h" />
69 <ClInclude Include="precomp.h" /> 70 <ClInclude Include="precomp.h" />
71 <ClInclude Include="TestRegistryFixture.h" />
70 <ClInclude Include="VariableHelpers.h" /> 72 <ClInclude Include="VariableHelpers.h" />
71 </ItemGroup> 73 </ItemGroup>
72 74
diff --git a/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj.filters b/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj.filters
index f9461f53..96563fc6 100644
--- a/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj.filters
+++ b/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj.filters
@@ -42,6 +42,9 @@
42 <ClCompile Include="SearchTest.cpp"> 42 <ClCompile Include="SearchTest.cpp">
43 <Filter>Source Files</Filter> 43 <Filter>Source Files</Filter>
44 </ClCompile> 44 </ClCompile>
45 <ClCompile Include="TestRegistryFixture.cpp">
46 <Filter>Source Files</Filter>
47 </ClCompile>
45 <ClCompile Include="VariableHelpers.cpp"> 48 <ClCompile Include="VariableHelpers.cpp">
46 <Filter>Source Files</Filter> 49 <Filter>Source Files</Filter>
47 </ClCompile> 50 </ClCompile>
@@ -56,19 +59,22 @@
56 <ClInclude Include="BurnTestException.h"> 59 <ClInclude Include="BurnTestException.h">
57 <Filter>Header Files</Filter> 60 <Filter>Header Files</Filter>
58 </ClInclude> 61 </ClInclude>
59 <ClInclude Include="ManifestHelpers.h"> 62 <ClInclude Include="BurnTestFixture.h">
60 <Filter>Header Files</Filter> 63 <Filter>Header Files</Filter>
61 </ClInclude> 64 </ClInclude>
62 <ClInclude Include="precomp.h"> 65 <ClInclude Include="BurnUnitTest.h">
63 <Filter>Header Files</Filter> 66 <Filter>Header Files</Filter>
64 </ClInclude> 67 </ClInclude>
65 <ClInclude Include="VariableHelpers.h"> 68 <ClInclude Include="ManifestHelpers.h">
66 <Filter>Header Files</Filter> 69 <Filter>Header Files</Filter>
67 </ClInclude> 70 </ClInclude>
68 <ClInclude Include="BurnUnitTest.h"> 71 <ClInclude Include="precomp.h">
69 <Filter>Header Files</Filter> 72 <Filter>Header Files</Filter>
70 </ClInclude> 73 </ClInclude>
71 <ClInclude Include="BurnTestFixture.h"> 74 <ClInclude Include="TestRegistryFixture.h">
75 <Filter>Header Files</Filter>
76 </ClInclude>
77 <ClInclude Include="VariableHelpers.h">
72 <Filter>Header Files</Filter> 78 <Filter>Header Files</Filter>
73 </ClInclude> 79 </ClInclude>
74 </ItemGroup> 80 </ItemGroup>
diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
index 2ebab277..f3645893 100644
--- a/src/burn/test/BurnUnitTest/RegistrationTest.cpp
+++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
@@ -3,43 +3,11 @@
3#include "precomp.h" 3#include "precomp.h"
4 4
5 5
6#define ROOT_PATH L"SOFTWARE\\WiX_Burn_UnitTest"
7#define HKLM_PATH ROOT_PATH L"\\HKLM"
8#define HKCU_PATH ROOT_PATH L"\\HKCU"
9#define REGISTRY_UNINSTALL_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" 6#define REGISTRY_UNINSTALL_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
10#define REGISTRY_RUN_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce" 7#define REGISTRY_RUN_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"
11#define TEST_BUNDLE_ID L"{D54F896D-1952-43E6-9C67-B5652240618C}" 8#define TEST_BUNDLE_ID L"{D54F896D-1952-43E6-9C67-B5652240618C}"
12#define TEST_BUNDLE_UPGRADE_CODE L"{89FDAE1F-8CC1-48B9-B930-3945E0D3E7F0}" 9#define TEST_BUNDLE_UPGRADE_CODE L"{89FDAE1F-8CC1-48B9-B930-3945E0D3E7F0}"
13 10
14#define TEST_UNINSTALL_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_UNINSTALL_KEY L"\\" TEST_BUNDLE_ID
15#define TEST_RUN_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_RUN_KEY
16#define TEST_VARIABLE_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_UNINSTALL_KEY L"\\" TEST_BUNDLE_ID L"\\variables"
17
18
19static LSTATUS APIENTRY RegistrationTest_RegCreateKeyExW(
20 __in HKEY hKey,
21 __in LPCWSTR lpSubKey,
22 __reserved DWORD Reserved,
23 __in_opt LPWSTR lpClass,
24 __in DWORD dwOptions,
25 __in REGSAM samDesired,
26 __in_opt CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes,
27 __out PHKEY phkResult,
28 __out_opt LPDWORD lpdwDisposition
29 );
30static LSTATUS APIENTRY RegistrationTest_RegOpenKeyExW(
31 __in HKEY hKey,
32 __in_opt LPCWSTR lpSubKey,
33 __reserved DWORD ulOptions,
34 __in REGSAM samDesired,
35 __out PHKEY phkResult
36 );
37static LSTATUS APIENTRY RegistrationTest_RegDeleteKeyExW(
38 __in HKEY hKey,
39 __in LPCWSTR lpSubKey,
40 __in REGSAM samDesired,
41 __reserved DWORD Reserved
42 );
43 11
44namespace Microsoft 12namespace Microsoft
45{ 13{
@@ -55,12 +23,23 @@ namespace Bootstrapper
55 using namespace System; 23 using namespace System;
56 using namespace System::IO; 24 using namespace System::IO;
57 using namespace Xunit; 25 using namespace Xunit;
26 using namespace WixBuildTools::TestSupport;
58 27
59 public ref class RegistrationTest : BurnUnitTest 28 public ref class RegistrationTest : BurnUnitTest, IClassFixture<TestRegistryFixture^>
60 { 29 {
30 private:
31 TestRegistryFixture^ testRegistry;
32 String^ testRunKeyPath;
33 String^ testUninstallKeyPath;
34 String^ testVariableKeyPath;
61 public: 35 public:
62 RegistrationTest(BurnTestFixture^ fixture) : BurnUnitTest(fixture) 36 RegistrationTest(BurnTestFixture^ fixture, TestRegistryFixture^ registryFixture) : BurnUnitTest(fixture)
63 { 37 {
38 this->testRegistry = registryFixture;
39
40 this->testRunKeyPath = this->testRegistry->GetDirectHkcuPath(gcnew String(REGISTRY_RUN_KEY));
41 this->testUninstallKeyPath = this->testRegistry->GetDirectHkcuPath(gcnew String(REGISTRY_UNINSTALL_KEY), gcnew String(TEST_BUNDLE_ID));
42 this->testVariableKeyPath = Path::Combine(this->testUninstallKeyPath, gcnew String(L"variables"));
64 } 43 }
65 44
66 [Fact] 45 [Fact]
@@ -79,14 +58,12 @@ namespace Bootstrapper
79 BURN_CACHE cache = { }; 58 BURN_CACHE cache = { };
80 BURN_ENGINE_COMMAND internalCommand = { }; 59 BURN_ENGINE_COMMAND internalCommand = { };
81 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 60 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
61 String^ cacheExePath = Path::Combine(cacheDirectory, gcnew String(L"setup.exe"));
82 DWORD dwRegistrationOptions = BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE; 62 DWORD dwRegistrationOptions = BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE;
83 63
84 try 64 try
85 { 65 {
86 // set mock API's 66 this->testRegistry->SetUp();
87 RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL);
88
89 Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH));
90 67
91 logging.sczPath = L"BurnUnitTest.txt"; 68 logging.sczPath = L"BurnUnitTest.txt";
92 69
@@ -133,8 +110,8 @@ namespace Bootstrapper
133 Assert::True(Directory::Exists(cacheDirectory)); 110 Assert::True(Directory::Exists(cacheDirectory));
134 Assert::True(File::Exists(Path::Combine(cacheDirectory, gcnew String(L"setup.exe")))); 111 Assert::True(File::Exists(Path::Combine(cacheDirectory, gcnew String(L"setup.exe"))));
135 112
136 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 113 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ACTIVE));
137 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr))); 114 this->ValidateRunOnceKeyEntry(cacheExePath);
138 115
139 // end session 116 // end session
140 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 117 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
@@ -143,8 +120,8 @@ namespace Bootstrapper
143 // verify that registration was removed 120 // verify that registration was removed
144 Assert::False(Directory::Exists(cacheDirectory)); 121 Assert::False(Directory::Exists(cacheDirectory));
145 122
146 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 123 this->ValidateUninstallKeyNull(L"Resume");
147 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 124 this->ValidateRunOnceKeyString(TEST_BUNDLE_ID, nullptr);
148 } 125 }
149 finally 126 finally
150 { 127 {
@@ -154,13 +131,12 @@ namespace Bootstrapper
154 RegistrationUninitialize(&registration); 131 RegistrationUninitialize(&registration);
155 VariablesUninitialize(&variables); 132 VariablesUninitialize(&variables);
156 133
157 Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH));
158 if (Directory::Exists(cacheDirectory)) 134 if (Directory::Exists(cacheDirectory))
159 { 135 {
160 Directory::Delete(cacheDirectory, true); 136 Directory::Delete(cacheDirectory, true);
161 } 137 }
162 138
163 RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 139 this->testRegistry->TearDown();
164 } 140 }
165 } 141 }
166 142
@@ -180,13 +156,11 @@ namespace Bootstrapper
180 BURN_CACHE cache = { }; 156 BURN_CACHE cache = { };
181 BURN_ENGINE_COMMAND internalCommand = { }; 157 BURN_ENGINE_COMMAND internalCommand = { };
182 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 158 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
159 String^ cacheExePath = Path::Combine(cacheDirectory, gcnew String(L"setup.exe"));
183 DWORD dwRegistrationOptions = 0; 160 DWORD dwRegistrationOptions = 0;
184 try 161 try
185 { 162 {
186 // set mock API's 163 this->testRegistry->SetUp();
187 RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL);
188
189 Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH));
190 164
191 logging.sczPath = L"BurnUnitTest.txt"; 165 logging.sczPath = L"BurnUnitTest.txt";
192 166
@@ -234,18 +208,18 @@ namespace Bootstrapper
234 TestThrowOnFailure(hr, L"Failed to register bundle."); 208 TestThrowOnFailure(hr, L"Failed to register bundle.");
235 209
236 // verify that registration was created 210 // verify that registration was created
237 Assert::Equal<String^>(gcnew String(L"Product1 Installation"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr)); 211 this->ValidateUninstallKeyDisplayName(L"Product1 Installation");
238 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 212 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ACTIVE));
239 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 213 this->ValidateRunOnceKeyEntry(cacheExePath);
240 214
241 // complete registration 215 // complete registration
242 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 216 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
243 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 217 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
244 218
245 // verify that registration was updated 219 // verify that registration was updated
246 Assert::Equal(Int32(BURN_RESUME_MODE_ARP), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 220 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ARP));
247 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 221 this->ValidateUninstallKeyInstalled(1);
248 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 222 this->ValidateRunOnceKeyString(TEST_BUNDLE_ID, nullptr);
249 223
250 // 224 //
251 // uninstall 225 // uninstall
@@ -256,18 +230,18 @@ namespace Bootstrapper
256 TestThrowOnFailure(hr, L"Failed to register bundle."); 230 TestThrowOnFailure(hr, L"Failed to register bundle.");
257 231
258 // verify that registration was updated 232 // verify that registration was updated
259 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 233 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ACTIVE));
260 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 234 this->ValidateUninstallKeyInstalled(1);
261 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 235 this->ValidateRunOnceKeyEntry(cacheExePath);
262 236
263 // delete registration 237 // delete registration
264 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 238 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
265 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 239 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
266 240
267 // verify that registration was removed 241 // verify that registration was removed
268 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 242 this->ValidateUninstallKeyNull(L"Resume");
269 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 243 this->ValidateUninstallKeyNull(L"Installed");
270 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 244 this->ValidateRunOnceKeyString(TEST_BUNDLE_ID, nullptr);
271 } 245 }
272 finally 246 finally
273 { 247 {
@@ -277,13 +251,12 @@ namespace Bootstrapper
277 RegistrationUninitialize(&registration); 251 RegistrationUninitialize(&registration);
278 VariablesUninitialize(&variables); 252 VariablesUninitialize(&variables);
279 253
280 Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH));
281 if (Directory::Exists(cacheDirectory)) 254 if (Directory::Exists(cacheDirectory))
282 { 255 {
283 Directory::Delete(cacheDirectory, true); 256 Directory::Delete(cacheDirectory, true);
284 } 257 }
285 258
286 RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 259 this->testRegistry->TearDown();
287 } 260 }
288 } 261 }
289 262
@@ -303,13 +276,11 @@ namespace Bootstrapper
303 BURN_CACHE cache = { }; 276 BURN_CACHE cache = { };
304 BURN_ENGINE_COMMAND internalCommand = { }; 277 BURN_ENGINE_COMMAND internalCommand = { };
305 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 278 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
279 String^ cacheExePath = Path::Combine(cacheDirectory, gcnew String(L"setup.exe"));
306 DWORD dwRegistrationOptions = 0; 280 DWORD dwRegistrationOptions = 0;
307 try 281 try
308 { 282 {
309 // set mock API's 283 this->testRegistry->SetUp();
310 RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL);
311
312 Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH));
313 284
314 logging.sczPath = L"BurnUnitTest.txt"; 285 logging.sczPath = L"BurnUnitTest.txt";
315 286
@@ -357,15 +328,15 @@ namespace Bootstrapper
357 TestThrowOnFailure(hr, L"Failed to register bundle."); 328 TestThrowOnFailure(hr, L"Failed to register bundle.");
358 329
359 // verify that registration was created 330 // verify that registration was created
360 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 331 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ACTIVE));
361 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 332 this->ValidateRunOnceKeyEntry(cacheExePath);
362 333
363 // complete registration 334 // complete registration
364 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BOOTSTRAPPER_REGISTRATION_TYPE_FULL); 335 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
365 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 336 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
366 337
367 // verify that registration variables were updated 338 // verify that registration variables were updated
368 Assert::Equal<String^>(gcnew String(L"Product1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr)); 339 this->ValidateUninstallKeyDisplayName(L"Product1");
369 registration.fInstalled = TRUE; 340 registration.fInstalled = TRUE;
370 341
371 hr = RegistrationSetVariables(&registration, &variables); 342 hr = RegistrationSetVariables(&registration, &variables);
@@ -385,9 +356,9 @@ namespace Bootstrapper
385 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 356 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
386 357
387 // verify that registration was removed 358 // verify that registration was removed
388 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 359 this->ValidateUninstallKeyNull(L"Resume");
389 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 360 this->ValidateUninstallKeyNull(L"Installed");
390 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 361 this->ValidateRunOnceKeyString(TEST_BUNDLE_ID, nullptr);
391 } 362 }
392 finally 363 finally
393 { 364 {
@@ -397,13 +368,12 @@ namespace Bootstrapper
397 RegistrationUninitialize(&registration); 368 RegistrationUninitialize(&registration);
398 VariablesUninitialize(&variables); 369 VariablesUninitialize(&variables);
399 370
400 Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH));
401 if (Directory::Exists(cacheDirectory)) 371 if (Directory::Exists(cacheDirectory))
402 { 372 {
403 Directory::Delete(cacheDirectory, true); 373 Directory::Delete(cacheDirectory, true);
404 } 374 }
405 375
406 RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 376 this->testRegistry->TearDown();
407 } 377 }
408 } 378 }
409 379
@@ -423,13 +393,11 @@ namespace Bootstrapper
423 BURN_CACHE cache = { }; 393 BURN_CACHE cache = { };
424 BURN_ENGINE_COMMAND internalCommand = { }; 394 BURN_ENGINE_COMMAND internalCommand = { };
425 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 395 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
396 String^ cacheExePath = Path::Combine(cacheDirectory, gcnew String(L"setup.exe"));
426 DWORD dwRegistrationOptions = 0; 397 DWORD dwRegistrationOptions = 0;
427 try 398 try
428 { 399 {
429 // set mock API's 400 this->testRegistry->SetUp();
430 RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL);
431
432 Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH));
433 401
434 logging.sczPath = L"BurnUnitTest.txt"; 402 logging.sczPath = L"BurnUnitTest.txt";
435 403
@@ -479,29 +447,29 @@ namespace Bootstrapper
479 TestThrowOnFailure(hr, L"Failed to register bundle."); 447 TestThrowOnFailure(hr, L"Failed to register bundle.");
480 448
481 // verify that registration was created 449 // verify that registration was created
482 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 450 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ACTIVE));
483 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 451 this->ValidateRunOnceKeyEntry(cacheExePath);
484 452
485 // finish registration 453 // finish registration
486 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_FULL); 454 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
487 TestThrowOnFailure(hr, L"Failed to register bundle."); 455 TestThrowOnFailure(hr, L"Failed to register bundle.");
488 456
489 // verify that registration was updated 457 // verify that registration was updated
490 Assert::Equal(Int32(BURN_RESUME_MODE_ARP), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 458 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ARP));
491 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 459 this->ValidateUninstallKeyInstalled(1);
492 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 460 this->ValidateRunOnceKeyString(TEST_BUNDLE_ID, nullptr);
493 461
494 Assert::Equal<String^>(gcnew String(L"DisplayName1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr)); 462 this->ValidateUninstallKeyDisplayName(L"DisplayName1");
495 Assert::Equal<String^>(gcnew String(L"1.2.3.4"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayVersion"), nullptr)); 463 this->ValidateUninstallKeyString(L"DisplayVersion", L"1.2.3.4");
496 Assert::Equal<String^>(gcnew String(L"Publisher1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Publisher"), nullptr)); 464 this->ValidateUninstallKeyString(L"Publisher", L"Publisher1");
497 Assert::Equal<String^>(gcnew String(L"http://www.microsoft.com/help"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"HelpLink"), nullptr)); 465 this->ValidateUninstallKeyString(L"HelpLink", L"http://www.microsoft.com/help");
498 Assert::Equal<String^>(gcnew String(L"555-555-5555"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"HelpTelephone"), nullptr)); 466 this->ValidateUninstallKeyString(L"HelpTelephone", L"555-555-5555");
499 Assert::Equal<String^>(gcnew String(L"http://www.microsoft.com/about"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"URLInfoAbout"), nullptr)); 467 this->ValidateUninstallKeyString(L"URLInfoAbout", L"http://www.microsoft.com/about");
500 Assert::Equal<String^>(gcnew String(L"http://www.microsoft.com/update"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"URLUpdateInfo"), nullptr)); 468 this->ValidateUninstallKeyString(L"URLUpdateInfo", L"http://www.microsoft.com/update");
501 Assert::Equal<String^>(gcnew String(L"Comments1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Comments"), nullptr)); 469 this->ValidateUninstallKeyString(L"Comments", L"Comments1");
502 Assert::Equal<String^>(gcnew String(L"Contact1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Contact"), nullptr)); 470 this->ValidateUninstallKeyString(L"Contact", L"Contact1");
503 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"NoModify"), nullptr)); 471 this->ValidateUninstallKeyNumber(L"NoModify", 1);
504 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"NoRemove"), nullptr)); 472 this->ValidateUninstallKeyNumber(L"NoRemove", 1);
505 473
506 // 474 //
507 // uninstall 475 // uninstall
@@ -512,17 +480,17 @@ namespace Bootstrapper
512 TestThrowOnFailure(hr, L"Failed to register bundle."); 480 TestThrowOnFailure(hr, L"Failed to register bundle.");
513 481
514 // verify that registration was updated 482 // verify that registration was updated
515 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 483 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ACTIVE));
516 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 484 this->ValidateRunOnceKeyEntry(cacheExePath);
517 485
518 // delete registration 486 // delete registration
519 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 487 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
520 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 488 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
521 489
522 // verify that registration was removed 490 // verify that registration was removed
523 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 491 this->ValidateUninstallKeyNull(L"Resume");
524 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 492 this->ValidateUninstallKeyNull(L"Installed");
525 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 493 this->ValidateRunOnceKeyString(TEST_BUNDLE_ID, nullptr);
526 } 494 }
527 finally 495 finally
528 { 496 {
@@ -532,13 +500,12 @@ namespace Bootstrapper
532 RegistrationUninitialize(&registration); 500 RegistrationUninitialize(&registration);
533 VariablesUninitialize(&variables); 501 VariablesUninitialize(&variables);
534 502
535 Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH));
536 if (Directory::Exists(cacheDirectory)) 503 if (Directory::Exists(cacheDirectory))
537 { 504 {
538 Directory::Delete(cacheDirectory, true); 505 Directory::Delete(cacheDirectory, true);
539 } 506 }
540 507
541 RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 508 this->testRegistry->TearDown();
542 } 509 }
543 } 510 }
544 511
@@ -567,10 +534,7 @@ namespace Bootstrapper
567 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 534 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
568 try 535 try
569 { 536 {
570 // set mock API's 537 this->testRegistry->SetUp();
571 RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL);
572
573 Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH));
574 538
575 logging.sczPath = L"BurnUnitTest.txt"; 539 logging.sczPath = L"BurnUnitTest.txt";
576 540
@@ -641,10 +605,10 @@ namespace Bootstrapper
641 cbBuffer = 0; 605 cbBuffer = 0;
642 606
643 // Verify the variables exist 607 // Verify the variables exist
644 Assert::Equal<String^>(gcnew String(L"42"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable1"), nullptr)); 608 this->ValidateVariableKey(L"MyBurnVariable1", gcnew String(L"42"));
645 Assert::Equal<String^>(gcnew String(L"bar"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable2"), nullptr)); 609 this->ValidateVariableKey(L"MyBurnVariable2", gcnew String(L"bar"));
646 Assert::Equal<String^>(gcnew String(L"1.0-beta"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable3"), nullptr)); 610 this->ValidateVariableKey(L"MyBurnVariable3", gcnew String(L"1.0-beta"));
647 Assert::Empty((System::Collections::IEnumerable ^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"WixBundleForcedRestartPackage"), nullptr)); 611 this->ValidateVariableKeyEmpty(L"WixBundleForcedRestartPackage");
648 612
649 hr = StrAlloc(&sczRelatedBundleId, MAX_GUID_CHARS + 1); 613 hr = StrAlloc(&sczRelatedBundleId, MAX_GUID_CHARS + 1);
650 NativeAssert::Succeeded(hr, "Failed to allocate buffer for related bundle id."); 614 NativeAssert::Succeeded(hr, "Failed to allocate buffer for related bundle id.");
@@ -674,13 +638,12 @@ namespace Bootstrapper
674 RegistrationUninitialize(&registration); 638 RegistrationUninitialize(&registration);
675 VariablesUninitialize(&variables); 639 VariablesUninitialize(&variables);
676 640
677 Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH));
678 if (Directory::Exists(cacheDirectory)) 641 if (Directory::Exists(cacheDirectory))
679 { 642 {
680 Directory::Delete(cacheDirectory, true); 643 Directory::Delete(cacheDirectory, true);
681 } 644 }
682 645
683 RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 646 this->testRegistry->TearDown();
684 } 647 }
685 } 648 }
686 649
@@ -705,13 +668,11 @@ namespace Bootstrapper
705 SIZE_T cbBuffer = 0; 668 SIZE_T cbBuffer = 0;
706 SIZE_T piBuffer = 0; 669 SIZE_T piBuffer = 0;
707 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 670 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
671 String^ cacheExePath = Path::Combine(cacheDirectory, gcnew String(L"setup.exe"));
708 DWORD dwRegistrationOptions = 0; 672 DWORD dwRegistrationOptions = 0;
709 try 673 try
710 { 674 {
711 // set mock API's 675 this->testRegistry->SetUp();
712 RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL);
713
714 Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH));
715 676
716 logging.sczPath = L"BurnUnitTest.txt"; 677 logging.sczPath = L"BurnUnitTest.txt";
717 678
@@ -786,10 +747,10 @@ namespace Bootstrapper
786 cbBuffer = 0; 747 cbBuffer = 0;
787 748
788 // Verify the variables exist 749 // Verify the variables exist
789 Assert::Equal<String^>(gcnew String(L"42"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable1"), nullptr)); 750 this->ValidateVariableKey(L"MyBurnVariable1", gcnew String(L"42"));
790 Assert::Equal<String^>(gcnew String(L"bar"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable2"), nullptr)); 751 this->ValidateVariableKey(L"MyBurnVariable2", gcnew String(L"bar"));
791 Assert::Equal<String^>(gcnew String(L"1.0-beta"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable3"), nullptr)); 752 this->ValidateVariableKey(L"MyBurnVariable3", gcnew String(L"1.0-beta"));
792 Assert::Empty((System::Collections::IEnumerable^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"WixBundleForcedRestartPackage"), nullptr)); 753 this->ValidateVariableKeyEmpty(L"WixBundleForcedRestartPackage");
793 754
794 hr = BundleGetBundleVariable(TEST_BUNDLE_ID, L"MyBurnVariable1", &sczValue); 755 hr = BundleGetBundleVariable(TEST_BUNDLE_ID, L"MyBurnVariable1", &sczValue);
795 TestThrowOnFailure(hr, L"Failed to read MyBurnVariable1."); 756 TestThrowOnFailure(hr, L"Failed to read MyBurnVariable1.");
@@ -807,7 +768,7 @@ namespace Bootstrapper
807 TestThrowOnFailure(hr, L"Failed to suspend session."); 768 TestThrowOnFailure(hr, L"Failed to suspend session.");
808 769
809 // verify that run key was removed 770 // verify that run key was removed
810 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 771 this->ValidateRunOnceKeyString(TEST_BUNDLE_ID, nullptr);
811 772
812 // read suspend resume type 773 // read suspend resume type
813 hr = RegistrationDetectResumeType(&registration, &resumeType); 774 hr = RegistrationDetectResumeType(&registration, &resumeType);
@@ -827,7 +788,7 @@ namespace Bootstrapper
827 TestThrowOnFailure(hr, L"Failed to write active resume mode."); 788 TestThrowOnFailure(hr, L"Failed to write active resume mode.");
828 789
829 // verify that run key was put back 790 // verify that run key was put back
830 Assert::NotEqual((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 791 this->ValidateRunOnceKeyEntry(cacheExePath);
831 792
832 // end session 793 // end session
833 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 794 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
@@ -847,155 +808,67 @@ namespace Bootstrapper
847 RegistrationUninitialize(&registration); 808 RegistrationUninitialize(&registration);
848 VariablesUninitialize(&variables); 809 VariablesUninitialize(&variables);
849 810
850 Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH));
851 if (Directory::Exists(cacheDirectory)) 811 if (Directory::Exists(cacheDirectory))
852 { 812 {
853 Directory::Delete(cacheDirectory, true); 813 Directory::Delete(cacheDirectory, true);
854 } 814 }
855 815
856 RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 816 this->testRegistry->TearDown();
857 } 817 }
858 } 818 }
859 819
860 //BOOTSTRAPPER_RESUME_TYPE_NONE, 820 void ValidateRunOnceKeyString(LPCWSTR valueName, String^ expected)
861 //BOOTSTRAPPER_RESUME_TYPE_INVALID, // resume information is present but invalid
862 //BOOTSTRAPPER_RESUME_TYPE_UNEXPECTED, // relaunched after an unexpected interruption
863 //BOOTSTRAPPER_RESUME_TYPE_REBOOT, // relaunched after reboot
864 //BOOTSTRAPPER_RESUME_TYPE_SUSPEND, // relaunched after suspend
865 //BOOTSTRAPPER_RESUME_TYPE_ARP, // launched from ARP
866 };
867}
868}
869}
870}
871}
872
873
874static LSTATUS APIENTRY RegistrationTest_RegCreateKeyExW(
875 __in HKEY hKey,
876 __in LPCWSTR lpSubKey,
877 __reserved DWORD Reserved,
878 __in_opt LPWSTR lpClass,
879 __in DWORD dwOptions,
880 __in REGSAM samDesired,
881 __in_opt CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes,
882 __out PHKEY phkResult,
883 __out_opt LPDWORD lpdwDisposition
884 )
885{
886 LSTATUS ls = ERROR_SUCCESS;
887 LPCWSTR wzRoot = NULL;
888 HKEY hkRoot = NULL;
889
890 if (HKEY_LOCAL_MACHINE == hKey)
891 {
892 wzRoot = HKLM_PATH;
893 }
894 else if (HKEY_CURRENT_USER == hKey)
895 {
896 wzRoot = HKCU_PATH;
897 }
898 else
899 {
900 hkRoot = hKey;
901 }
902
903 if (wzRoot)
904 {
905 ls = ::RegOpenKeyExW(HKEY_CURRENT_USER, wzRoot, 0, KEY_WRITE, &hkRoot);
906 if (ERROR_SUCCESS != ls)
907 { 821 {
908 ExitFunction(); 822 WixAssert::StringEqual(expected, (String^)Registry::GetValue(this->testRunKeyPath, gcnew String(valueName), nullptr), false);
909 } 823 }
910 }
911 824
912 ls = ::RegCreateKeyExW(hkRoot, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); 825 void ValidateRunOnceKeyEntry(String^ exePath)
913
914LExit:
915 ReleaseRegKey(hkRoot);
916
917 return ls;
918}
919
920static LSTATUS APIENTRY RegistrationTest_RegOpenKeyExW(
921 __in HKEY hKey,
922 __in_opt LPCWSTR lpSubKey,
923 __reserved DWORD ulOptions,
924 __in REGSAM samDesired,
925 __out PHKEY phkResult
926 )
927{
928 LSTATUS ls = ERROR_SUCCESS;
929 LPCWSTR wzRoot = NULL;
930 HKEY hkRoot = NULL;
931
932 if (HKEY_LOCAL_MACHINE == hKey)
933 {
934 wzRoot = HKLM_PATH;
935 }
936 else if (HKEY_CURRENT_USER == hKey)
937 {
938 wzRoot = HKCU_PATH;
939 }
940 else
941 {
942 hkRoot = hKey;
943 }
944
945 if (wzRoot)
946 {
947 ls = ::RegOpenKeyExW(HKEY_CURRENT_USER, wzRoot, 0, KEY_WRITE, &hkRoot);
948 if (ERROR_SUCCESS != ls)
949 { 826 {
950 ExitFunction(); 827 this->ValidateRunOnceKeyString(TEST_BUNDLE_ID, String::Concat(L"\"", exePath, L"\" /burn.clean.room /burn.runonce"));
951 } 828 }
952 }
953 829
954 ls = ::RegOpenKeyExW(hkRoot, lpSubKey, ulOptions, samDesired, phkResult); 830 void ValidateUninstallKeyNull(LPCWSTR valueName)
955 831 {
956LExit: 832 Assert::Null(Registry::GetValue(this->testUninstallKeyPath, gcnew String(valueName), nullptr));
957 ReleaseRegKey(hkRoot); 833 }
958 834
959 return ls; 835 void ValidateUninstallKeyNumber(LPCWSTR valueName, Int32 expected)
960} 836 {
837 Assert::Equal(expected, (Int32)Registry::GetValue(this->testUninstallKeyPath, gcnew String(valueName), nullptr));
838 }
961 839
962static LSTATUS APIENTRY RegistrationTest_RegDeleteKeyExW( 840 void ValidateUninstallKeyString(LPCWSTR valueName, String^ expected)
963 __in HKEY hKey, 841 {
964 __in LPCWSTR lpSubKey, 842 WixAssert::StringEqual(expected, (String^)Registry::GetValue(this->testUninstallKeyPath, gcnew String(valueName), nullptr), false);
965 __in REGSAM samDesired, 843 }
966 __reserved DWORD Reserved
967 )
968{
969 LSTATUS ls = ERROR_SUCCESS;
970 LPCWSTR wzRoot = NULL;
971 HKEY hkRoot = NULL;
972 844
973 if (HKEY_LOCAL_MACHINE == hKey) 845 void ValidateUninstallKeyDisplayName(String^ expected)
974 { 846 {
975 wzRoot = HKLM_PATH; 847 this->ValidateUninstallKeyString(L"DisplayName", expected);
976 } 848 }
977 else if (HKEY_CURRENT_USER == hKey)
978 {
979 wzRoot = HKCU_PATH;
980 }
981 else
982 {
983 hkRoot = hKey;
984 }
985 849
986 if (wzRoot) 850 void ValidateUninstallKeyInstalled(Int32 expected)
987 {
988 ls = ::RegOpenKeyExW(HKEY_CURRENT_USER, wzRoot, 0, KEY_WRITE | samDesired, &hkRoot);
989 if (ERROR_SUCCESS != ls)
990 { 851 {
991 ExitFunction(); 852 this->ValidateUninstallKeyNumber(L"Installed", expected);
992 } 853 }
993 }
994 854
995 ls = ::RegDeleteKeyExW(hkRoot, lpSubKey, samDesired, Reserved); 855 void ValidateUninstallKeyResume(Int32 expected)
856 {
857 this->ValidateUninstallKeyNumber(L"Resume", expected);
858 }
996 859
997LExit: 860 void ValidateVariableKey(LPCWSTR valueName, String^ expected)
998 ReleaseRegKey(hkRoot); 861 {
862 WixAssert::StringEqual(expected, (String^)Registry::GetValue(this->testVariableKeyPath, gcnew String(valueName), nullptr), false);
863 }
999 864
1000 return ls; 865 void ValidateVariableKeyEmpty(LPCWSTR valueName)
866 {
867 Assert::Empty((System::Collections::IEnumerable^)Registry::GetValue(this->testVariableKeyPath, gcnew String(valueName), nullptr));
868 }
869 };
870}
871}
872}
873}
1001} 874}
diff --git a/src/burn/test/BurnUnitTest/TestRegistryFixture.cpp b/src/burn/test/BurnUnitTest/TestRegistryFixture.cpp
new file mode 100644
index 00000000..3e78c6f5
--- /dev/null
+++ b/src/burn/test/BurnUnitTest/TestRegistryFixture.cpp
@@ -0,0 +1,184 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5#define TEST_REGISTRY_FIXTURE_ROOT_PATH L"SOFTWARE\\WiX_Burn_UnitTest"
6#define TEST_REGISTRY_FIXTURE_HKLM_PATH TEST_REGISTRY_FIXTURE_ROOT_PATH L"\\HKLM"
7#define TEST_REGISTRY_FIXTURE_HKCU_PATH TEST_REGISTRY_FIXTURE_ROOT_PATH L"\\HKCU"
8
9static LSTATUS APIENTRY TestRegistryFixture_RegCreateKeyExW(
10 __in HKEY hKey,
11 __in LPCWSTR lpSubKey,
12 __reserved DWORD Reserved,
13 __in_opt LPWSTR lpClass,
14 __in DWORD dwOptions,
15 __in REGSAM samDesired,
16 __in_opt CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes,
17 __out PHKEY phkResult,
18 __out_opt LPDWORD lpdwDisposition
19 )
20{
21 LSTATUS ls = ERROR_SUCCESS;
22 LPCWSTR wzRoot = NULL;
23 HKEY hkRoot = NULL;
24
25 if (HKEY_LOCAL_MACHINE == hKey)
26 {
27 wzRoot = TEST_REGISTRY_FIXTURE_HKLM_PATH;
28 }
29 else if (HKEY_CURRENT_USER == hKey)
30 {
31 wzRoot = TEST_REGISTRY_FIXTURE_HKCU_PATH;
32 }
33 else
34 {
35 hkRoot = hKey;
36 }
37
38 if (wzRoot)
39 {
40 ls = ::RegOpenKeyExW(HKEY_CURRENT_USER, wzRoot, 0, KEY_WRITE, &hkRoot);
41 if (ERROR_SUCCESS != ls)
42 {
43 ExitFunction();
44 }
45 }
46
47 ls = ::RegCreateKeyExW(hkRoot, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
48
49LExit:
50 ReleaseRegKey(hkRoot);
51
52 return ls;
53}
54
55static LSTATUS APIENTRY TestRegistryFixture_RegOpenKeyExW(
56 __in HKEY hKey,
57 __in_opt LPCWSTR lpSubKey,
58 __reserved DWORD ulOptions,
59 __in REGSAM samDesired,
60 __out PHKEY phkResult
61 )
62{
63 LSTATUS ls = ERROR_SUCCESS;
64 LPCWSTR wzRoot = NULL;
65 HKEY hkRoot = NULL;
66
67 if (HKEY_LOCAL_MACHINE == hKey)
68 {
69 wzRoot = TEST_REGISTRY_FIXTURE_HKLM_PATH;
70 }
71 else if (HKEY_CURRENT_USER == hKey)
72 {
73 wzRoot = TEST_REGISTRY_FIXTURE_HKCU_PATH;
74 }
75 else
76 {
77 hkRoot = hKey;
78 }
79
80 if (wzRoot)
81 {
82 ls = ::RegOpenKeyExW(HKEY_CURRENT_USER, wzRoot, 0, KEY_WRITE, &hkRoot);
83 if (ERROR_SUCCESS != ls)
84 {
85 ExitFunction();
86 }
87 }
88
89 ls = ::RegOpenKeyExW(hkRoot, lpSubKey, ulOptions, samDesired, phkResult);
90
91LExit:
92 ReleaseRegKey(hkRoot);
93
94 return ls;
95}
96
97static LSTATUS APIENTRY TestRegistryFixture_RegDeleteKeyExW(
98 __in HKEY hKey,
99 __in LPCWSTR lpSubKey,
100 __in REGSAM samDesired,
101 __reserved DWORD Reserved
102 )
103{
104 LSTATUS ls = ERROR_SUCCESS;
105 LPCWSTR wzRoot = NULL;
106 HKEY hkRoot = NULL;
107
108 if (HKEY_LOCAL_MACHINE == hKey)
109 {
110 wzRoot = TEST_REGISTRY_FIXTURE_HKLM_PATH;
111 }
112 else if (HKEY_CURRENT_USER == hKey)
113 {
114 wzRoot = TEST_REGISTRY_FIXTURE_HKCU_PATH;
115 }
116 else
117 {
118 hkRoot = hKey;
119 }
120
121 if (wzRoot)
122 {
123 ls = ::RegOpenKeyExW(HKEY_CURRENT_USER, wzRoot, 0, KEY_WRITE | samDesired, &hkRoot);
124 if (ERROR_SUCCESS != ls)
125 {
126 ExitFunction();
127 }
128 }
129
130 ls = ::RegDeleteKeyExW(hkRoot, lpSubKey, samDesired, Reserved);
131
132LExit:
133 ReleaseRegKey(hkRoot);
134
135 return ls;
136}
137
138namespace WixBuildTools
139{
140 namespace TestSupport
141 {
142 using namespace System;
143 using namespace System::IO;
144 using namespace Microsoft::Win32;
145
146 TestRegistryFixture::TestRegistryFixture()
147 {
148 this->rootPath = gcnew String(TEST_REGISTRY_FIXTURE_ROOT_PATH);
149 this->hkcuPath = gcnew String(TEST_REGISTRY_FIXTURE_HKCU_PATH);
150 this->hklmPath = gcnew String(TEST_REGISTRY_FIXTURE_HKLM_PATH);
151 }
152
153 TestRegistryFixture::~TestRegistryFixture()
154 {
155 this->TearDown();
156 }
157
158 void TestRegistryFixture::SetUp()
159 {
160 // set mock API's
161 RegFunctionOverride(TestRegistryFixture_RegCreateKeyExW, TestRegistryFixture_RegOpenKeyExW, TestRegistryFixture_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL);
162
163 Registry::CurrentUser->CreateSubKey(this->hkcuPath);
164 Registry::CurrentUser->CreateSubKey(this->hklmPath);
165 }
166
167 void TestRegistryFixture::TearDown()
168 {
169 Registry::CurrentUser->DeleteSubKeyTree(this->rootPath, false);
170
171 RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
172 }
173
174 String^ TestRegistryFixture::GetDirectHkcuPath(... array<String^>^ paths)
175 {
176 return Path::Combine(Registry::CurrentUser->Name, this->hkcuPath, Path::Combine(paths));
177 }
178
179 String^ TestRegistryFixture::GetDirectHklmPath(... array<String^>^ paths)
180 {
181 return Path::Combine(Registry::CurrentUser->Name, this->hklmPath, Path::Combine(paths));
182 }
183 }
184}
diff --git a/src/burn/test/BurnUnitTest/TestRegistryFixture.h b/src/burn/test/BurnUnitTest/TestRegistryFixture.h
new file mode 100644
index 00000000..283efe42
--- /dev/null
+++ b/src/burn/test/BurnUnitTest/TestRegistryFixture.h
@@ -0,0 +1,30 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4namespace WixBuildTools
5{
6namespace TestSupport
7{
8 using namespace System;
9
10 public ref class TestRegistryFixture : IDisposable
11 {
12 private:
13 String^ rootPath;
14 String^ hkcuPath;
15 String^ hklmPath;
16 public:
17 TestRegistryFixture();
18
19 ~TestRegistryFixture();
20
21 void SetUp();
22
23 void TearDown();
24
25 String^ GetDirectHkcuPath(... array<String^>^ paths);
26
27 String^ GetDirectHklmPath(... array<String^>^ paths);
28 };
29}
30}
diff --git a/src/burn/test/BurnUnitTest/precomp.h b/src/burn/test/BurnUnitTest/precomp.h
index a31917b4..ecab3494 100644
--- a/src/burn/test/BurnUnitTest/precomp.h
+++ b/src/burn/test/BurnUnitTest/precomp.h
@@ -78,3 +78,4 @@
78#include "BurnUnitTest.h" 78#include "BurnUnitTest.h"
79#include "VariableHelpers.h" 79#include "VariableHelpers.h"
80#include "ManifestHelpers.h" 80#include "ManifestHelpers.h"
81#include "TestRegistryFixture.h"