diff options
author | Rob Mensching <rob@firegiant.com> | 2022-03-31 11:56:14 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2022-03-31 18:01:06 -0700 |
commit | 47582b162368e8edf7a3b11c13b8e9dabc5f0a26 (patch) | |
tree | 2c4063eff325684bed39de0edacd7866a257ae02 /src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs | |
parent | 167296c42497c4e95f0d5d71168542d747655981 (diff) | |
download | wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.tar.gz wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.tar.bz2 wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.zip |
Provide managed CA and Embedded UI DTF libraries via NuGet
Lots of refactoring to bring the SFX tooling back into the 'dtf'
layer since they are (in the end) tightly coupled to some DTF
assemblies. Also refactored the DTF tests into their own folder
and added a couple integration tests to build using the new CA/UI
NuGet package.
Closes wixtoolset/issues#6080
Diffstat (limited to 'src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs')
-rw-r--r-- | src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs new file mode 100644 index 00000000..f994dfef --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs | |||
@@ -0,0 +1,409 @@ | |||
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 | namespace WixToolset.Dtf.Test | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Windows.Forms; | ||
8 | using System.Globalization; | ||
9 | using System.Collections.Generic; | ||
10 | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
11 | using WixToolset.Dtf.WindowsInstaller; | ||
12 | using View = WixToolset.Dtf.WindowsInstaller.View; | ||
13 | |||
14 | [TestClass] | ||
15 | public class WindowsInstallerTest | ||
16 | { | ||
17 | public WindowsInstallerTest() | ||
18 | { | ||
19 | } | ||
20 | |||
21 | [TestInitialize()] | ||
22 | public void Initialize() | ||
23 | { | ||
24 | } | ||
25 | |||
26 | [TestCleanup()] | ||
27 | public void Cleanup() | ||
28 | { | ||
29 | } | ||
30 | |||
31 | [TestMethod] | ||
32 | [Ignore] // Currently fails. | ||
33 | public void InstallerErrorMessages() | ||
34 | { | ||
35 | string msg3002 = Installer.GetErrorMessage(3002); | ||
36 | Console.WriteLine("3002=" + msg3002); | ||
37 | Assert.IsNotNull(msg3002); | ||
38 | Assert.IsTrue(msg3002.Length > 0); | ||
39 | } | ||
40 | |||
41 | [TestMethod] | ||
42 | public void InstallerDatabaseSchema() | ||
43 | { | ||
44 | string dbFile = "InstallerDatabaseSchema.msi"; | ||
45 | |||
46 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
47 | { | ||
48 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
49 | db.Commit(); | ||
50 | } | ||
51 | |||
52 | Assert.IsTrue(File.Exists(dbFile), "Checking whether created database file " + dbFile + " exists."); | ||
53 | |||
54 | using (Database db = new Database(dbFile, DatabaseOpenMode.ReadOnly)) | ||
55 | { | ||
56 | TableCollection tables = db.Tables; | ||
57 | Assert.AreEqual<int>(Schema.Tables.Count, tables.Count, "Counting tables."); | ||
58 | Assert.AreEqual<int>(Schema.Property.Columns.Count, tables["Property"].Columns.Count, "Counting columns in Property table."); | ||
59 | |||
60 | foreach (TableInfo tableInfo in tables) | ||
61 | { | ||
62 | Console.WriteLine(tableInfo.Name); | ||
63 | foreach (ColumnInfo columnInfo in tableInfo.Columns) | ||
64 | { | ||
65 | Console.WriteLine("\t{0} {1}", columnInfo.Name, columnInfo.ColumnDefinitionString); | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | |||
71 | [TestMethod] | ||
72 | public void InstallerViewTables() | ||
73 | { | ||
74 | string dbFile = "InstallerViewTables.msi"; | ||
75 | |||
76 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
77 | { | ||
78 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
79 | db.Commit(); | ||
80 | |||
81 | using (View view1 = db.OpenView("SELECT `Property`, `Value` FROM `Property` WHERE `Value` IS NOT NULL")) | ||
82 | { | ||
83 | IList<TableInfo> viewTables = view1.Tables; | ||
84 | Assert.IsNotNull(viewTables); | ||
85 | Assert.AreEqual<int>(1, viewTables.Count); | ||
86 | Assert.AreEqual<String>("Property", viewTables[0].Name); | ||
87 | } | ||
88 | |||
89 | using (View view2 = db.OpenView("INSERT INTO `Property` (`Property`, `Value`) VALUES ('TestViewTables', 1)")) | ||
90 | { | ||
91 | IList<TableInfo> viewTables = view2.Tables; | ||
92 | Assert.IsNotNull(viewTables); | ||
93 | Assert.AreEqual<int>(1, viewTables.Count); | ||
94 | Assert.AreEqual<String>("Property", viewTables[0].Name); | ||
95 | } | ||
96 | |||
97 | using (View view3 = db.OpenView("UPDATE `Property` SET `Value` = 2 WHERE `Property` = 'TestViewTables'")) | ||
98 | { | ||
99 | IList<TableInfo> viewTables = view3.Tables; | ||
100 | Assert.IsNotNull(viewTables); | ||
101 | Assert.AreEqual<int>(1, viewTables.Count); | ||
102 | Assert.AreEqual<String>("Property", viewTables[0].Name); | ||
103 | } | ||
104 | |||
105 | using (View view4 = db.OpenView("alter table Property hold")) | ||
106 | { | ||
107 | IList<TableInfo> viewTables = view4.Tables; | ||
108 | Assert.IsNotNull(viewTables); | ||
109 | Assert.AreEqual<int>(1, viewTables.Count); | ||
110 | Assert.AreEqual<String>("Property", viewTables[0].Name); | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | |||
115 | [TestMethod] | ||
116 | public void InstallerInstallProduct() | ||
117 | { | ||
118 | string dbFile = "InstallerInstallProduct.msi"; | ||
119 | string productCode; | ||
120 | |||
121 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
122 | { | ||
123 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
124 | WindowsInstallerUtils.CreateTestProduct(db); | ||
125 | |||
126 | productCode = db.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0]; | ||
127 | |||
128 | db.Commit(); | ||
129 | } | ||
130 | |||
131 | ProductInstallation installation = new ProductInstallation(productCode); | ||
132 | Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed before starting."); | ||
133 | |||
134 | Installer.SetInternalUI(InstallUIOptions.Silent); | ||
135 | ExternalUIHandler prevHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUILogger, | ||
136 | InstallLogModes.FatalExit | | ||
137 | InstallLogModes.Error | | ||
138 | InstallLogModes.Warning | | ||
139 | InstallLogModes.User | | ||
140 | InstallLogModes.Info | | ||
141 | InstallLogModes.ResolveSource | | ||
142 | InstallLogModes.OutOfDiskSpace | | ||
143 | InstallLogModes.ActionStart | | ||
144 | InstallLogModes.ActionData | | ||
145 | InstallLogModes.CommonData | | ||
146 | InstallLogModes.Progress | | ||
147 | InstallLogModes.Initialize | | ||
148 | InstallLogModes.Terminate | | ||
149 | InstallLogModes.ShowDialog); | ||
150 | Assert.IsNull(prevHandler, "Checking that returned previous UI handler is null."); | ||
151 | |||
152 | Exception caughtEx = null; | ||
153 | try | ||
154 | { | ||
155 | Installer.InstallProduct(dbFile, String.Empty); | ||
156 | } | ||
157 | catch (Exception ex) { caughtEx = ex; } | ||
158 | Assert.IsNull(caughtEx, "Exception thrown while installing product: " + caughtEx); | ||
159 | |||
160 | prevHandler = Installer.SetExternalUI(prevHandler, InstallLogModes.None); | ||
161 | Assert.AreEqual<ExternalUIHandler>(WindowsInstallerTest.ExternalUILogger, prevHandler, "Checking that previously-set UI handler is returned."); | ||
162 | |||
163 | Assert.IsTrue(installation.IsInstalled, "Checking that product is installed."); | ||
164 | Console.WriteLine(); | ||
165 | Console.WriteLine(); | ||
166 | Console.WriteLine(); | ||
167 | Console.WriteLine("==================================================================="); | ||
168 | Console.WriteLine(); | ||
169 | Console.WriteLine(); | ||
170 | Console.WriteLine(); | ||
171 | |||
172 | ExternalUIRecordHandler prevRecHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUIRecordLogger, | ||
173 | InstallLogModes.FatalExit | | ||
174 | InstallLogModes.Error | | ||
175 | InstallLogModes.Warning | | ||
176 | InstallLogModes.User | | ||
177 | InstallLogModes.Info | | ||
178 | InstallLogModes.ResolveSource | | ||
179 | InstallLogModes.OutOfDiskSpace | | ||
180 | InstallLogModes.ActionStart | | ||
181 | InstallLogModes.ActionData | | ||
182 | InstallLogModes.CommonData | | ||
183 | InstallLogModes.Progress | | ||
184 | InstallLogModes.Initialize | | ||
185 | InstallLogModes.Terminate | | ||
186 | InstallLogModes.ShowDialog); | ||
187 | Assert.IsNull(prevRecHandler, "Checking that returned previous UI record handler is null."); | ||
188 | |||
189 | try | ||
190 | { | ||
191 | Installer.InstallProduct(dbFile, "REMOVE=All"); | ||
192 | } | ||
193 | catch (Exception ex) { caughtEx = ex; } | ||
194 | Assert.IsNull(caughtEx, "Exception thrown while installing product: " + caughtEx); | ||
195 | |||
196 | Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed after removing."); | ||
197 | |||
198 | prevRecHandler = Installer.SetExternalUI(prevRecHandler, InstallLogModes.None); | ||
199 | Assert.AreEqual<ExternalUIRecordHandler>(WindowsInstallerTest.ExternalUIRecordLogger, prevRecHandler, "Checking that previously-set UI record handler is returned."); | ||
200 | } | ||
201 | |||
202 | public static MessageResult ExternalUILogger( | ||
203 | InstallMessage messageType, | ||
204 | string message, | ||
205 | MessageButtons buttons, | ||
206 | MessageIcon icon, | ||
207 | MessageDefaultButton defaultButton) | ||
208 | { | ||
209 | Console.WriteLine("{0}: {1}", messageType, message); | ||
210 | return MessageResult.None; | ||
211 | } | ||
212 | |||
213 | public static MessageResult ExternalUIRecordLogger( | ||
214 | InstallMessage messageType, | ||
215 | Record messageRecord, | ||
216 | MessageButtons buttons, | ||
217 | MessageIcon icon, | ||
218 | MessageDefaultButton defaultButton) | ||
219 | { | ||
220 | if (messageRecord != null) | ||
221 | { | ||
222 | if (messageRecord.FormatString.Length == 0 && messageRecord.FieldCount > 0) | ||
223 | { | ||
224 | messageRecord.FormatString = "1: [1] 2: [2] 3: [3] 4: [4] 5: [5]"; | ||
225 | } | ||
226 | Console.WriteLine("{0}: {1}", messageType, messageRecord.ToString()); | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | Console.WriteLine("{0}: (null)", messageType); | ||
231 | } | ||
232 | return MessageResult.None; | ||
233 | } | ||
234 | |||
235 | [TestMethod] | ||
236 | [Ignore] // Currently fails. | ||
237 | public void InstallerMessageResources() | ||
238 | { | ||
239 | string message1101 = Installer.GetErrorMessage(1101); | ||
240 | Console.WriteLine("Message 1101: " + message1101); | ||
241 | Assert.IsNotNull(message1101); | ||
242 | Assert.IsTrue(message1101.Contains("file")); | ||
243 | |||
244 | message1101 = Installer.GetErrorMessage(1101, CultureInfo.GetCultureInfo(1033)); | ||
245 | Console.WriteLine("Message 1101: " + message1101); | ||
246 | Assert.IsNotNull(message1101); | ||
247 | Assert.IsTrue(message1101.Contains("file")); | ||
248 | |||
249 | string message2621 = Installer.GetErrorMessage(2621); | ||
250 | Console.WriteLine("Message 2621: " + message2621); | ||
251 | Assert.IsNotNull(message2621); | ||
252 | Assert.IsTrue(message2621.Contains("DLL")); | ||
253 | |||
254 | string message3002 = Installer.GetErrorMessage(3002); | ||
255 | Console.WriteLine("Message 3002: " + message3002); | ||
256 | Assert.IsNotNull(message3002); | ||
257 | Assert.IsTrue(message3002.Contains("sequencing")); | ||
258 | } | ||
259 | |||
260 | [TestMethod] | ||
261 | public void EnumComponentQualifiers() | ||
262 | { | ||
263 | foreach (ComponentInstallation comp in ComponentInstallation.AllComponents) | ||
264 | { | ||
265 | bool qualifiers = false; | ||
266 | foreach (ComponentInstallation.Qualifier qualifier in comp.Qualifiers) | ||
267 | { | ||
268 | if (!qualifiers) | ||
269 | { | ||
270 | Console.WriteLine(comp.Path); | ||
271 | qualifiers = true; | ||
272 | } | ||
273 | |||
274 | Console.WriteLine("\t{0}: {1}", qualifier.QualifierCode, qualifier.Data); | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | |||
279 | [TestMethod] | ||
280 | public void DeleteRecord() | ||
281 | { | ||
282 | string dbFile = "DeleteRecord.msi"; | ||
283 | |||
284 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
285 | { | ||
286 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
287 | WindowsInstallerUtils.CreateTestProduct(db); | ||
288 | |||
289 | string query = "SELECT `Property`, `Value` FROM `Property` WHERE `Property` = 'UpgradeCode'"; | ||
290 | |||
291 | using (View view = db.OpenView(query)) | ||
292 | { | ||
293 | view.Execute(); | ||
294 | |||
295 | Record rec = view.Fetch(); | ||
296 | |||
297 | Console.WriteLine("Calling ToString() : " + rec); | ||
298 | |||
299 | view.Delete(rec); | ||
300 | } | ||
301 | |||
302 | Assert.AreEqual(0, db.ExecuteStringQuery(query).Count); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | [TestMethod] | ||
307 | public void InsertRecordThenTryFormatString() | ||
308 | { | ||
309 | string dbFile = "InsertRecordThenTryFormatString.msi"; | ||
310 | |||
311 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
312 | { | ||
313 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
314 | WindowsInstallerUtils.CreateTestProduct(db); | ||
315 | |||
316 | string parameterFormatString = "[1]"; | ||
317 | string[] properties = new string[] | ||
318 | { | ||
319 | "SonGoku", "Over 9000", | ||
320 | }; | ||
321 | |||
322 | string query = "SELECT `Property`, `Value` FROM `Property`"; | ||
323 | |||
324 | using (View view = db.OpenView(query)) | ||
325 | { | ||
326 | using (Record rec = new Record(2)) | ||
327 | { | ||
328 | rec[1] = properties[0]; | ||
329 | rec[2] = properties[1]; | ||
330 | rec.FormatString = parameterFormatString; | ||
331 | Console.WriteLine("Format String before inserting: " + rec.FormatString); | ||
332 | view.Insert(rec); | ||
333 | |||
334 | Console.WriteLine("Format String after inserting: " + rec.FormatString); | ||
335 | // After inserting, the format string is invalid. | ||
336 | Assert.AreEqual(String.Empty, rec.ToString()); | ||
337 | |||
338 | // Setting the format string manually makes it valid again. | ||
339 | rec.FormatString = parameterFormatString; | ||
340 | Assert.AreEqual(properties[0], rec.ToString()); | ||
341 | } | ||
342 | } | ||
343 | } | ||
344 | } | ||
345 | |||
346 | [TestMethod] | ||
347 | public void SeekRecordThenTryFormatString() | ||
348 | { | ||
349 | string dbFile = "SeekRecordThenTryFormatString.msi"; | ||
350 | |||
351 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
352 | { | ||
353 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
354 | WindowsInstallerUtils.CreateTestProduct(db); | ||
355 | |||
356 | string parameterFormatString = "[1]"; | ||
357 | string[] properties = new string[] | ||
358 | { | ||
359 | "SonGoku", "Over 9000", | ||
360 | }; | ||
361 | |||
362 | string query = "SELECT `Property`, `Value` FROM `Property`"; | ||
363 | |||
364 | using (View view = db.OpenView(query)) | ||
365 | { | ||
366 | using (Record rec = new Record(2)) | ||
367 | { | ||
368 | rec[1] = properties[0]; | ||
369 | rec[2] = properties[1]; | ||
370 | rec.FormatString = parameterFormatString; | ||
371 | Console.WriteLine("Record fields before seeking: " + rec[0] + " " + rec[1] + " " + rec[2]); | ||
372 | view.Seek(rec); | ||
373 | |||
374 | //TODO: Why does view.Seek remove the record fields? | ||
375 | Console.WriteLine("Record fields after seeking: " + rec[0] + " " + rec[1] + " " + rec[2]); | ||
376 | // After inserting, the format string is invalid. | ||
377 | Assert.AreEqual(String.Empty, rec.ToString()); | ||
378 | } | ||
379 | } | ||
380 | } | ||
381 | } | ||
382 | |||
383 | [TestMethod] | ||
384 | public void TestToString() | ||
385 | { | ||
386 | string defaultString = "1: "; | ||
387 | string vegetaShout = "It's OVER 9000!!"; | ||
388 | string gokuPowerLevel = "9001"; | ||
389 | string nappaInquiry = "Vegeta, what's the Scouter say about his power level?"; | ||
390 | string parameterFormatString = "[1]"; | ||
391 | |||
392 | Record rec = new Record(1); | ||
393 | Assert.AreEqual(defaultString, rec.ToString(), "Testing default FormatString"); | ||
394 | |||
395 | rec.FormatString = String.Empty; | ||
396 | Assert.AreEqual(defaultString, rec.ToString(), "Explicitly set the FormatString to the empty string."); | ||
397 | |||
398 | rec.FormatString = vegetaShout; | ||
399 | Assert.AreEqual(vegetaShout, rec.ToString(), "Testing text only (empty FormatString)"); | ||
400 | |||
401 | rec.FormatString = gokuPowerLevel; | ||
402 | Assert.AreEqual(gokuPowerLevel, rec.ToString(), "Testing numbers only from a record that wasn't fetched."); | ||
403 | |||
404 | Record rec2 = new Record(nappaInquiry); | ||
405 | rec2.FormatString = parameterFormatString; | ||
406 | Assert.AreEqual(nappaInquiry, rec2.ToString(), "Testing text with a FormatString set."); | ||
407 | } | ||
408 | } | ||
409 | } | ||