main
cs 406 lines 18.5 KB
Raw
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 WixToolsetTest.CoreIntegration
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.Data;
8 using System.IO;
9 using System.Linq;
10 using WixInternal.Core.TestPackage;
11 using WixInternal.TestSupport;
12 using WixToolset.Data.WindowsInstaller;
13 using Xunit;
14
15 public class HarvestFilesFixture
16 {
17 [Fact]
18 public void MustIncludeSomeFiles()
19 {
20 Build("BadAuthoring.wxs", (_, result) =>
21 {
22 var messages = result.Messages.Select(m => m.Id);
23 Assert.Equal(new[]
24 {
25 10,
26 }, messages);
27 });
28 }
29
30 [Fact]
31 public void ZeroFilesHarvestedIsAWarning()
32 {
33 Build("ZeroFiles.wxs", (_, result) =>
34 {
35 var messages = result.Messages.Select(m => m.Id);
36 Assert.Equal(new[]
37 {
38 8600,
39 }, messages);
40 });
41 }
42
43 [Fact]
44 public void MissingHarvestDirectoryIsAWarning()
45 {
46 Build("BadDirectory.wxs", (_, result) =>
47 {
48 var messages = result.Messages.Select(m => m.Id);
49 Assert.Equal(new[]
50 {
51 8601,
52 8600,
53 8601,
54 8600,
55 }, messages);
56 });
57 }
58
59 [Fact]
60 public void DuplicateFilesSomethingSomething()
61 {
62 Build("DuplicateFiles.wxs", (_, result) =>
63 {
64 var messages = result.Messages.Select(m => m.Id);
65 Assert.Equal(new[]
66 {
67 8602,
68 8602,
69 8602,
70 8602,
71 }, messages);
72 });
73 }
74
75 [Fact]
76 public void HarvestedFilesUnderPackageWithAuthoredFeatureAreOrphaned()
77 {
78 Build("PackageWithoutDefaultFeature.wxs", (_, result) =>
79 {
80 var messages = result.Messages.Select(m => m.Id);
81 Assert.Equal(new[]
82 {
83 267,
84 267,
85 267,
86 267,
87 }, messages);
88 });
89 }
90
91 [Fact]
92 public void CanHarvestFilesInComponentGroup()
93 {
94 var expected = new[]
95 {
96 @"fls4di7CtiJhJnEwixr8_c5G8k8aNY=PFiles\MsiPackage\test3.txt",
97 @"flsk5E532wcxn9MfpYQYRnrPi3dsOA=PFiles\MsiPackage\test4.txt",
98 @"flsYh0SwdEpJEootWp2keHMLnnpeb4=PFiles\MsiPackage\files2_sub2\test20.txt",
99 @"flsI4uo74epTPY4TLIcWKVaH.HTbVQ=PFiles\MsiPackage\files2_sub2\test21.txt",
100 @"fls5xOtTcUOA9ZDnUsz1D4Arbw7l_A=PFiles\MsiPackage\files2_sub3\FileName.Extension",
101 };
102
103 Build("ComponentGroup.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
104 }
105
106 [Fact]
107 public void CanHarvestFilesInDirectory()
108 {
109 var expected = new[]
110 {
111 @"flsD7JQZm.Ts2375WMT.zsTxqCAf.s=PFiles\MsiPackage\files1_sub1\test10.txt",
112 @"flslrDWblm4pE.4i4jR58_XyYMmR8I=PFiles\MsiPackage\files1_sub1\files1_sub2\test120.txt",
113 @"flsj.cb0sFWqIPHPFSKJSEEaPDuAQ4=PFiles\MsiPackage\test2.txt",
114 @"flsaFu0CvigRX6Psea0ic6ZWevzLmI=PFiles\MsiPackage\test3.txt",
115 @"flsJBy_HKCNejalUyud4HisGqhd72E=PFiles\MsiPackage\test4.txt",
116 };
117
118 Build("Directory.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
119 }
120
121 [Fact]
122 public void CanHarvestFilesInDirectoryRef()
123 {
124 var expected = new[]
125 {
126 @"flsYgiwrDUkZnBEK6iUMkxxaJlD8yQ=PFiles\MsiPackage\test1.txt",
127 @"flsj.cb0sFWqIPHPFSKJSEEaPDuAQ4=PFiles\MsiPackage\test2.txt",
128 @"flslrDWblm4pE.4i4jR58_XyYMmR8I=PFiles\MsiPackage\files1_sub1\files1_sub2\test120.txt",
129 @"flsIpBotASYdALXxudRqekdQdKEKdQ=PFiles\MsiPackage\notatest.txt",
130 @"flsaFu0CvigRX6Psea0ic6ZWevzLmI=PFiles\MsiPackage\test3.txt",
131 @"flsJBy_HKCNejalUyud4HisGqhd72E=PFiles\MsiPackage\test4.txt",
132 @"flsLXU67KiOVU00lZL1jaDaBVpg.Dw=PFiles\MsiPackage\files2_sub2\pleasedontincludeme.dat",
133 @"fls05.yw49T0FVAq3Wvq2ihNp3KWfI=PFiles\MsiPackage\files2_sub2\test20.txt",
134 @"flsf0falU_gCTJjtbSCNiFpJQ1d8EM=PFiles\MsiPackage\files2_sub2\test21.txt",
135 };
136
137 Build("DirectoryRef.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
138 }
139
140 [Fact]
141 public void CanHarvestFilesInFeature()
142 {
143 var expected = new[]
144 {
145 @"flsFGp4MRR_h3Qm.CuBFwC0AJo6b6M=PFiles\Example Product\test2.txt",
146 @"flsTCB.ifIor30C7HfezIDjMB3mrdk=PFiles\Example Product\Assets\test3.txt",
147 @"flsTIP5QnXmYzSzwEM2casYcyn1eR4=PFiles\Example Product\Assets\test4.txt",
148 };
149
150 Build("Feature.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
151 }
152
153 [Fact]
154 public void CanHarvestFilesInFeatureGroup()
155 {
156 var expected = new[]
157 {
158 @"flsYgiwrDUkZnBEK6iUMkxxaJlD8yQ=PFiles\MsiPackage\test1.txt",
159 @"flsj.cb0sFWqIPHPFSKJSEEaPDuAQ4=PFiles\MsiPackage\test2.txt",
160 @"flsXCzqPnLIc2S0BUeTH_BHeaHJgbw=PFiles\MsiPackage\assets\notatest.txt",
161 @"flsiPGfLix0PMEZQ.BGdIfMp43g0m0=PFiles\MsiPackage\assets\test3.txt",
162 @"flsQp7vl8wg1R6a9pWOuj0y8X9tFdk=PFiles\MsiPackage\assets\test4.txt",
163 @"flsROfaiHyEp8AGBy4ZIkz26B8x0QE=PFiles\MsiPackage\assets\files2_sub2\pleasedontincludeme.dat",
164 @"flsR7cMdABXp6bHg2a89trPLf9NuKU=PFiles\MsiPackage\assets\files2_sub2\test20.txt",
165 @"flse0V.F.q.LFFjytlCECxjK5io7g0=PFiles\MsiPackage\assets\files2_sub2\test21.txt",
166 @"flsQk6.O4lkg78pGc4Ye64mosdl3hY=PFiles\MsiPackage\assets\files2_sub3\FileName.Extension",
167 };
168
169 Build("FeatureGroup.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
170 }
171
172 [Fact]
173 public void CanHarvestFilesInStraightAndCrookedTrees()
174 {
175 var expected = new[]
176 {
177 @"flsKwXKj_Znab7ED_V5tgmdm6I35Mk=PFiles\root\a\file.ext",
178 @"flsG_e554dKs4hJ6VckjXfvHVbrQ_c=PFiles\root\b\file.ext",
179 @"fls6QPA6Lio8i18jzGOvfZpb2vxh9M=PFiles\root\c\file.ext",
180 @"flsfPnakkQEQynhlS0Z9wVZMXLjKx4=PFiles\root\d\file.ext",
181 @"fls9z8lqK0ZvjlnUEzCDIE7bF01zXU=PFiles\root\e\file.ext",
182 @"flsFqGICaLl5ZLPsdJY.Z2m6xC2Khs=PFiles\root\f\file.ext",
183 @"flsUT96SVd6kTNE4X7vBFL7r3Zl4sM=PFiles\root\g\file.ext",
184 @"fls.i3qm35eVOQoWBJFaj3c9792GKc=PFiles\root\h\file.ext",
185 @"flsgKGasxQIkFWfpTA6kQurqEL4Afg=PFiles\root\file.ext",
186 @"flsZGaHZm_l9M8jaQS8XSgxnlykcKI=PFiles\root\z\y\x\w\v\u\t\s\r\q\file.ext",
187 };
188
189 Build("CrookedTree.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
190 }
191
192 [Fact]
193 public void CanHarvestFilesInFeatureRef()
194 {
195 var expected = new[]
196 {
197 @"flsYgiwrDUkZnBEK6iUMkxxaJlD8yQ=PFiles\MsiPackage\test1.txt",
198 @"flsj.cb0sFWqIPHPFSKJSEEaPDuAQ4=PFiles\MsiPackage\test2.txt",
199 @"flsXCzqPnLIc2S0BUeTH_BHeaHJgbw=PFiles\MsiPackage\assets\notatest.txt",
200 @"flsiPGfLix0PMEZQ.BGdIfMp43g0m0=PFiles\MsiPackage\assets\test3.txt",
201 @"flsQp7vl8wg1R6a9pWOuj0y8X9tFdk=PFiles\MsiPackage\assets\test4.txt",
202 @"flsROfaiHyEp8AGBy4ZIkz26B8x0QE=PFiles\MsiPackage\assets\files2_sub2\pleasedontincludeme.dat",
203 @"flsR7cMdABXp6bHg2a89trPLf9NuKU=PFiles\MsiPackage\assets\files2_sub2\test20.txt",
204 @"flse0V.F.q.LFFjytlCECxjK5io7g0=PFiles\MsiPackage\assets\files2_sub2\test21.txt",
205 @"flsQk6.O4lkg78pGc4Ye64mosdl3hY=PFiles\MsiPackage\assets\files2_sub3\FileName.Extension",
206 };
207
208 Build("FeatureRef.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
209 }
210
211 [Fact]
212 public void CanHarvestFilesInFragments()
213 {
214 var expected = new[]
215 {
216 @"flsOQDmBHyBKZnyRziE3.z5HjmBv4k=PFiles\MsiPackage\test1.txt",
217 @"flsHjzoVbTTY2jQbthZHKG7Rn4yMZo=PFiles\MsiPackage\test2.txt",
218 @"flsPLx4KqFVkbnYyg3Uo4QdiRLFbL8=PFiles\MsiPackage\notatest.txt",
219 @"fls4di7CtiJhJnEwixr8_c5G8k8aNY=PFiles\MsiPackage\test3.txt",
220 @"flsk5E532wcxn9MfpYQYRnrPi3dsOA=PFiles\MsiPackage\test4.txt",
221 };
222
223 Build("Fragment.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
224 }
225
226 [Fact]
227 public void CanHarvestFilesInModules()
228 {
229 var expectedFilesAndTargetPaths = new[]
230 {
231 @"flsBvxG729t7hKBa4KOmfvNMPptZkM.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test4.txt",
232 @"flsDBWSWjpVSU3Zs33bREsJa2ygSQM.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test2.txt",
233 @"flsehdwEdXusUijRShuTszSxwf8joA.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test3.txt",
234 @"flsgrgAVAsCQ8tCCxfnbBNis66623c.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test1.txt",
235 @"flskqOUVMfAE13k2h.ZkPhurwO4Y1c.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\notatest.txt",
236 };
237
238 var expectedModuleComponents = new[]
239 {
240 "ModuleComponents:flsBvxG729t7hKBa4KOmfvNMPptZkM.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
241 "ModuleComponents:flsDBWSWjpVSU3Zs33bREsJa2ygSQM.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
242 "ModuleComponents:flsehdwEdXusUijRShuTszSxwf8joA.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
243 "ModuleComponents:flsgrgAVAsCQ8tCCxfnbBNis66623c.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
244 "ModuleComponents:flskqOUVMfAE13k2h.ZkPhurwO4Y1c.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
245 };
246
247 Build("Module.wxs", (msiPath, _) => AssertModuleComponentsFileIdsAndTargetPaths(msiPath, expectedFilesAndTargetPaths, expectedModuleComponents), isMsi: false);
248
249 static void AssertModuleComponentsFileIdsAndTargetPaths(string msiPath, string[] expectedFilesAndTargetPaths, string[] expectedModuleComponents)
250 {
251 AssertFileIdsAndTargetPaths(msiPath, expectedFilesAndTargetPaths);
252
253 var query = Query.QueryDatabase(msiPath, new[] { "ModuleComponents" });
254
255 Assert.Equal(expectedModuleComponents, query);
256 }
257 }
258
259 [Fact]
260 public void CanHarvestFilesWithNamedBindPaths()
261 {
262 var expected = new[]
263 {
264 @"flsNNsTNrgmjASmTBbP.45J1F50dEc=PFiles\HarvestedFiles\test1.txt",
265 @"flsASLR5pHQzLmWRE.Snra7ndH7sIA=PFiles\HarvestedFiles\test2.txt",
266 @"flsTZFPiMHb.qfUxdGKQYrnXOhZ.8M=PFiles\HarvestedFiles\files1_sub1\test10.txt",
267 @"flsLGcTTZPIU3ELiWybqnm.PQ0Ih_g=PFiles\HarvestedFiles\files1_sub1\files1_sub2\test120.txt",
268 @"fls1Jx2Y9Vea_.WZBH_h2e79arvDRU=PFiles\HarvestedFiles\test3.txt",
269 @"flsJ9gNxWaau2X3ufphQuCV9WwAgcw=PFiles\HarvestedFiles\test4.txt",
270 @"flswcmX9dpMQytmD_5QA5aJ5szoQVA=PFiles\HarvestedFiles\files2_sub2\test20.txt",
271 @"flskKeCKFUtCYMuvw564rgPLJmyBx0=PFiles\HarvestedFiles\files2_sub2\test21.txt",
272 @"fls2agLZFnQwjoijShwT9Z0RwHyGrI=PFiles\HarvestedFiles\files2_sub3\FileName.Extension",
273 };
274
275 Build("BindPaths.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
276 }
277
278 [Fact]
279 public void CanHarvestFilesWithUnnamedBindPaths()
280 {
281 var expected = new[]
282 {
283 @"flsNNsTNrgmjASmTBbP.45J1F50dEc=PFiles\HarvestedFiles\test1.txt",
284 @"flsASLR5pHQzLmWRE.Snra7ndH7sIA=PFiles\HarvestedFiles\test2.txt",
285 @"flsTZFPiMHb.qfUxdGKQYrnXOhZ.8M=PFiles\HarvestedFiles\files1_sub1\test10.txt",
286 @"flsLGcTTZPIU3ELiWybqnm.PQ0Ih_g=PFiles\HarvestedFiles\files1_sub1\files1_sub2\test120.txt",
287 @"fls1Jx2Y9Vea_.WZBH_h2e79arvDRU=PFiles\HarvestedFiles\test3.txt",
288 @"flsJ9gNxWaau2X3ufphQuCV9WwAgcw=PFiles\HarvestedFiles\test4.txt",
289 @"flswcmX9dpMQytmD_5QA5aJ5szoQVA=PFiles\HarvestedFiles\files2_sub2\test20.txt",
290 @"flskKeCKFUtCYMuvw564rgPLJmyBx0=PFiles\HarvestedFiles\files2_sub2\test21.txt",
291 @"fls2agLZFnQwjoijShwT9Z0RwHyGrI=PFiles\HarvestedFiles\files2_sub3\FileName.Extension",
292 @"fls9UMOE.TOv61JuYF8IhvCKb8eous=PFiles\HarvestedFiles\namedfile.txt",
293 @"flsu53T_9CcaBegDflAImGHTajDbJ0=PFiles\HarvestedFiles\unnamedfile.txt",
294 };
295
296 Build("BindPathsUnnamed.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected), addUnnamedBindPath: true);
297 }
298
299 [Fact]
300 public void CanHarvestFilesInStandardDirectory()
301 {
302 var expected = new[]
303 {
304 @"flsxKKnXWKGChnZD8KSNY4Mwb48nHc=PFiles\MsiPackage\test1.txt",
305 @"flsVa.JZ23qQ1vXrc1jjOLIyJMyuqM=PFiles\MsiPackage\test2.txt",
306 @"fls4_TTxMCivlzpVJiyNHQRa2eU2ZA=PFiles\MsiPackage\files1_sub1\test10.txt",
307 @"flsBQqnyJp3XnmzomCYT_1qJqKLeSA=PFiles\MsiPackage\files1_sub1\files1_sub2\test120.txt",
308 @"flsbr7Ii_L1MRmxOImvY3N7np5FqAU=PFiles\MsiPackage\notatest.txt",
309 @"fls5VacfuX4Iub..BmTvssAOUcUI1o=PFiles\MsiPackage\test3.txt",
310 @"flsTtxen6j9kDjhKw2rnKSlYn5e2_k=PFiles\MsiPackage\test4.txt",
311 @"flsKEAYr7hAov7KfiRTjHg1VBg6T38=PFiles\MsiPackage\files2_sub2\pleasedontincludeme.dat",
312 @"flsvw4WMs4foeBokT9VUN3qjPDg8jc=PFiles\MsiPackage\files2_sub2\test20.txt",
313 @"flspraz8bfD0UXdCBW9CS2jr49hl1k=PFiles\MsiPackage\files2_sub2\test21.txt",
314 @"flsCgt3Noa1VJHlHG5HOVjD5vdJm5Q=PFiles\MsiPackage\files2_sub3\FileName.Extension",
315 };
316
317 Build("StandardDirectory.wxs", (msiPath, result) =>
318 {
319 result.AssertSuccess();
320 AssertFileIdsAndTargetPaths(msiPath, expected);
321 }, warningsAsErrors: false);
322 }
323
324 [Fact]
325 public void CanHarvestFilesInFiveLines()
326 {
327 var expected = new[]
328 {
329 @"flsIpBotASYdALXxudRqekdQdKEKdQ=PFiles\Example Corporation MsiPackage\notatest.txt",
330 @"flsaFu0CvigRX6Psea0ic6ZWevzLmI=PFiles\Example Corporation MsiPackage\test3.txt",
331 @"flsJBy_HKCNejalUyud4HisGqhd72E=PFiles\Example Corporation MsiPackage\test4.txt",
332 @"flsLXU67KiOVU00lZL1jaDaBVpg.Dw=PFiles\Example Corporation MsiPackage\files2_sub2\pleasedontincludeme.dat",
333 @"fls05.yw49T0FVAq3Wvq2ihNp3KWfI=PFiles\Example Corporation MsiPackage\files2_sub2\test20.txt",
334 @"flsf0falU_gCTJjtbSCNiFpJQ1d8EM=PFiles\Example Corporation MsiPackage\files2_sub2\test21.txt",
335 @"fls6Dd0lNq_VzYLYjK7ty5WxNy5KCs=PFiles\Example Corporation MsiPackage\files2_sub3\FileName.Extension",
336 };
337
338 Build("PackageFiveLiner.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
339 }
340
341 [Fact]
342 public void CanGetVerboseHarvestingDetails()
343 {
344 Build("Feature.wxs", (_, result) =>
345 {
346 var messages = result.Messages.Select(m => m.Id).Where(i => i >= 8700 && i < 8800);
347 Assert.Equal(new[]
348 {
349 8701,
350 8700,
351 8701,
352 8700,
353 8700,
354 }, messages);
355 }, additionalCommandLineArguments: "-v");
356 }
357
358 private static void AssertFileIdsAndTargetPaths(string msiPath, string[] expected)
359 {
360 var pkg = new WixToolset.Dtf.WindowsInstaller.Package.InstallPackage(msiPath,
361 WixToolset.Dtf.WindowsInstaller.DatabaseOpenMode.ReadOnly);
362 var sortedExpected = expected.OrderBy(s => s);
363 var actual = pkg.Files.OrderBy(kvp => kvp.Key).Select(kvp => $"{kvp.Key}={kvp.Value.TargetPath}");
364
365 Assert.Equal(sortedExpected, actual);
366 }
367
368 private static void Build(string file, Action<string, WixRunnerResult> tester, bool isMsi = true, bool warningsAsErrors = true, bool addUnnamedBindPath = false, params string[] additionalCommandLineArguments)
369 {
370 var folder = TestData.Get("TestData", "HarvestFiles");
371
372 using (var fs = new DisposableFileSystem())
373 {
374 var baseFolder = fs.GetFolder();
375 var intermediateFolder = Path.Combine(baseFolder, "obj");
376 var binFolder = Path.Combine(baseFolder, "bin");
377 var msiPath = Path.Combine(binFolder, isMsi ? "test.msi" : "test.msm");
378
379 var arguments = new List<string>()
380 {
381 "build",
382 Path.Combine(folder, file),
383 "-intermediateFolder", intermediateFolder,
384 "-bindpath", @$"ToBeHarvested={folder}\files1",
385 "-bindpath", @$"ToBeHarvested={folder}\files2",
386 "-o", msiPath,
387 };
388
389 if (addUnnamedBindPath)
390 {
391 arguments.Add("-bindpath");
392 arguments.Add(Path.Combine(folder, "unnamedbindpath"));
393 }
394
395 if (additionalCommandLineArguments.Length > 0)
396 {
397 arguments.AddRange(additionalCommandLineArguments);
398 }
399
400 var result = WixRunner.Execute(warningsAsErrors, arguments.ToArray());
401
402 tester(msiPath, result);
403 }
404 }
405 }
406 }