aboutsummaryrefslogtreecommitdiff
path: root/src/test/WixToolsetTest.CoreIntegration/PatchFixture.cs
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-04-22 17:19:56 -0700
committerRob Mensching <rob@firegiant.com>2021-04-29 19:53:52 -0700
commit8cf0427984a88b0b3ddfb2061e5be721afffe82e (patch)
tree22e2aaf7665d5ab6d3dc2a8ce8f05d73080d1f20 /src/test/WixToolsetTest.CoreIntegration/PatchFixture.cs
parent8426095723fb8530a321260473ab543151bf8c98 (diff)
downloadwix-8cf0427984a88b0b3ddfb2061e5be721afffe82e.tar.gz
wix-8cf0427984a88b0b3ddfb2061e5be721afffe82e.tar.bz2
wix-8cf0427984a88b0b3ddfb2061e5be721afffe82e.zip
Move Core into wix
Diffstat (limited to 'src/test/WixToolsetTest.CoreIntegration/PatchFixture.cs')
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/PatchFixture.cs279
1 files changed, 0 insertions, 279 deletions
diff --git a/src/test/WixToolsetTest.CoreIntegration/PatchFixture.cs b/src/test/WixToolsetTest.CoreIntegration/PatchFixture.cs
deleted file mode 100644
index 483e3fd5..00000000
--- a/src/test/WixToolsetTest.CoreIntegration/PatchFixture.cs
+++ /dev/null
@@ -1,279 +0,0 @@
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
3namespace WixToolsetTest.CoreIntegration
4{
5 using System;
6 using System.Collections.Generic;
7 using System.ComponentModel;
8 using System.IO;
9 using System.Linq;
10 using System.Runtime.InteropServices;
11 using System.Text;
12 using System.Xml;
13 using System.Xml.Linq;
14 using Example.Extension;
15 using WixBuildTools.TestSupport;
16 using WixToolset.Core.TestPackage;
17 using WixToolset.Data;
18 using WixToolset.Data.Burn;
19 using Xunit;
20
21 public class PatchFixture
22 {
23 private static readonly XNamespace PatchNamespace = "http://www.microsoft.com/msi/patch_applicability.xsd";
24
25 [Fact]
26 public void CanBuildSimplePatch()
27 {
28 var folder = TestData.Get(@"TestData\PatchSingle");
29
30 using (var fs = new DisposableFileSystem())
31 {
32 var tempFolder = fs.GetFolder();
33
34 var baselinePdb = BuildMsi("Baseline.msi", folder, tempFolder, "1.0.0", "1.0.0", "1.0.0");
35 var update1Pdb = BuildMsi("Update.msi", folder, tempFolder, "1.0.1", "1.0.1", "1.0.1");
36 var patchPdb = BuildMsp("Patch1.msp", folder, tempFolder, "1.0.1");
37 var patchPath = Path.ChangeExtension(patchPdb, ".msp");
38
39 Assert.True(File.Exists(baselinePdb));
40 Assert.True(File.Exists(update1Pdb));
41
42 var doc = GetExtractPatchXml(patchPath);
43 Assert.Equal("{7D326855-E790-4A94-8611-5351F8321FCA}", doc.Root.Element(PatchNamespace + "TargetProductCode").Value);
44
45 var names = Query.GetSubStorageNames(patchPath);
46 Assert.Equal(new[] { "#RTM.1", "RTM.1" }, names);
47
48 var cab = Path.Combine(tempFolder, "foo.cab");
49 Query.ExtractStream(patchPath, "foo.cab", cab);
50 Assert.True(File.Exists(cab));
51
52 var files = Query.GetCabinetFiles(cab);
53 Assert.Equal(new[] { "a.txt", "b.txt" }, files.Select(f => f.Name).ToArray());
54 }
55 }
56
57 [Fact]
58 public void CanBuildSimplePatchWithNoFileChanges()
59 {
60 var folder = TestData.Get(@"TestData\PatchNoFileChanges");
61
62 using (var fs = new DisposableFileSystem())
63 {
64 var tempFolder = fs.GetFolder();
65
66 var baselinePdb = BuildMsi("Baseline.msi", folder, tempFolder, "1.0.0", "1.0.0", "1.0.0");
67 var update1Pdb = BuildMsi("Update.msi", folder, tempFolder, "1.0.1", "1.0.1", "1.0.1");
68 var patchPdb = BuildMsp("Patch1.msp", folder, tempFolder, "1.0.1", hasNoFiles: true);
69 var patchPath = Path.ChangeExtension(patchPdb, ".msp");
70
71 Assert.True(File.Exists(baselinePdb));
72 Assert.True(File.Exists(update1Pdb));
73
74 var doc = GetExtractPatchXml(patchPath);
75 Assert.Equal("{7D326855-E790-4A94-8611-5351F8321FCA}", doc.Root.Element(PatchNamespace + "TargetProductCode").Value);
76
77 var names = Query.GetSubStorageNames(patchPath);
78 Assert.Equal(new[] { "#RTM.1", "RTM.1" }, names);
79
80 var cab = Path.Combine(tempFolder, "foo.cab");
81 Query.ExtractStream(patchPath, "foo.cab", cab);
82 Assert.True(File.Exists(cab));
83
84 var files = Query.GetCabinetFiles(cab);
85 Assert.Empty(files);
86 }
87 }
88
89 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6387")]
90 public void CanBuildPatchFromProductWithFilesFromWixlib()
91 {
92 var folder = TestData.Get(@"TestData\PatchFromWixlib");
93
94 using (var fs = new DisposableFileSystem())
95 {
96 var tempFolderBaseline = fs.GetFolder();
97 var tempFolderUpdate = fs.GetFolder();
98 var tempFolderPatch = fs.GetFolder();
99
100 var baselinePdb = BuildMsi("Baseline.msi", folder, tempFolderBaseline, "1.0.0", "1.0.0", "1.0.0");
101 var update1Pdb = BuildMsi("Update.msi", folder, tempFolderUpdate, "1.0.1", "1.0.1", "1.0.1");
102 var patchPdb = BuildMsp("Patch1.msp", folder, tempFolderPatch, "1.0.1", bindpaths: new[] { Path.GetDirectoryName(baselinePdb), Path.GetDirectoryName(update1Pdb) }, hasNoFiles: true);
103 var patchPath = Path.ChangeExtension(patchPdb, ".msp");
104
105 Assert.True(File.Exists(baselinePdb));
106 Assert.True(File.Exists(update1Pdb));
107 }
108 }
109
110 [Fact]
111 public void CanBuildBundleWithNonSpecificPatches()
112 {
113 var folder = TestData.Get(@"TestData\PatchNonSpecific");
114
115 using (var fs = new DisposableFileSystem())
116 {
117 var tempFolder = fs.GetFolder();
118
119 var baselinePdb = BuildMsi("Baseline.msi", Path.Combine(folder, "PackageA"), tempFolder, "1.0.0", "A", "B");
120 var updatePdb = BuildMsi("Update.msi", Path.Combine(folder, "PackageA"), tempFolder, "1.0.1", "A", "B");
121 var patchAPdb = BuildMsp("PatchA.msp", Path.Combine(folder, "PatchA"), tempFolder, "1.0.1", hasNoFiles: true);
122 var patchBPdb = BuildMsp("PatchB.msp", Path.Combine(folder, "PatchB"), tempFolder, "1.0.1", hasNoFiles: true);
123 var patchCPdb = BuildMsp("PatchC.msp", Path.Combine(folder, "PatchC"), tempFolder, "1.0.1", hasNoFiles: true);
124 var bundleAPdb = BuildBundle("BundleA.exe", Path.Combine(folder, "BundleA"), tempFolder);
125 var bundleBPdb = BuildBundle("BundleB.exe", Path.Combine(folder, "BundleB"), tempFolder);
126 var bundleCPdb = BuildBundle("BundleC.exe", Path.Combine(folder, "BundleC"), tempFolder);
127
128 VerifyPatchTargetCodes(bundleAPdb, new[]
129 {
130 "<PatchTargetCode TargetCode='{26309973-0A5E-4979-B142-98A6E064EDC0}' Product='yes' />",
131 });
132 VerifyPatchTargetCodes(bundleBPdb, new[]
133 {
134 "<PatchTargetCode TargetCode='{26309973-0A5E-4979-B142-98A6E064EDC0}' Product='yes' />",
135 "<PatchTargetCode TargetCode='{32B0396A-CE36-4570-B16E-F88FA42DC409}' Product='no' />",
136 });
137 VerifyPatchTargetCodes(bundleCPdb, new string[0]);
138 }
139 }
140
141 [Fact]
142 public void CanBuildBundleWithSlipstreamPatch()
143 {
144 var folder = TestData.Get(@"TestData\PatchSingle");
145
146 using (var fs = new DisposableFileSystem())
147 {
148 var tempFolder = fs.GetFolder();
149
150 var baselinePdb = BuildMsi("Baseline.msi", folder, tempFolder, "1.0.0", "1.0.0", "1.0.0");
151 var update1Pdb = BuildMsi("Update.msi", folder, tempFolder, "1.0.1", "1.0.1", "1.0.1");
152 var patchPdb = BuildMsp("Patch1.msp", folder, tempFolder, "1.0.1");
153 var bundleAPdb = BuildBundle("BundleA.exe", Path.Combine(folder, "BundleA"), tempFolder);
154
155 using (var wixOutput = WixOutput.Read(bundleAPdb))
156 {
157 var manifestData = wixOutput.GetData(BurnConstants.BurnManifestWixOutputStreamName);
158 var doc = new XmlDocument();
159 doc.LoadXml(manifestData);
160 var nsmgr = BundleExtractor.GetBurnNamespaceManager(doc, "w");
161 var slipstreamMspNodes = doc.SelectNodes("/w:BurnManifest/w:Chain/w:MsiPackage/w:SlipstreamMsp", nsmgr);
162 Assert.Equal(1, slipstreamMspNodes.Count);
163 Assert.Equal("<SlipstreamMsp Id='PatchA' />", slipstreamMspNodes[0].GetTestXml());
164 }
165 }
166 }
167
168 private static void VerifyPatchTargetCodes(string pdbPath, string[] expected)
169 {
170 using (var wixOutput = WixOutput.Read(pdbPath))
171 {
172 var manifestData = wixOutput.GetData(BurnConstants.BurnManifestWixOutputStreamName);
173 var doc = new XmlDocument();
174 doc.LoadXml(manifestData);
175 var nsmgr = BundleExtractor.GetBurnNamespaceManager(doc, "w");
176 var patchTargetCodes = doc.SelectNodes("/w:BurnManifest/w:PatchTargetCode", nsmgr);
177
178 var actual = new List<string>();
179 foreach (XmlNode patchTargetCodeNode in patchTargetCodes)
180 {
181 actual.Add(patchTargetCodeNode.GetTestXml());
182 }
183
184 WixAssert.CompareLineByLine(expected, actual.ToArray());
185 }
186 }
187
188 private static string BuildMsi(string outputName, string sourceFolder, string baseFolder, string defineV, string defineA, string defineB)
189 {
190 var extensionPath = Path.GetFullPath(new Uri(typeof(ExampleExtensionFactory).Assembly.CodeBase).LocalPath);
191 var outputPath = Path.Combine(baseFolder, Path.Combine("bin", outputName));
192
193 var result = WixRunner.Execute(new[]
194 {
195 "build",
196 Path.Combine(sourceFolder, @"Package.wxs"),
197 "-d", "V=" + defineV,
198 "-d", "A=" + defineA,
199 "-d", "B=" + defineB,
200 "-bindpath", Path.Combine(sourceFolder, ".data"),
201 "-intermediateFolder", Path.Combine(baseFolder, "obj"),
202 "-o", outputPath,
203 "-ext", extensionPath,
204 });
205
206 result.AssertSuccess();
207
208 return Path.ChangeExtension(outputPath, ".wixpdb");
209 }
210
211 private static string BuildMsp(string outputName, string sourceFolder, string baseFolder, string defineV, IEnumerable<string> bindpaths = null, bool hasNoFiles = false)
212 {
213 var outputPath = Path.Combine(baseFolder, Path.Combine("bin", outputName));
214
215 var args = new List<string>
216 {
217 "build",
218 hasNoFiles ? "-sw1079" : " ",
219 Path.Combine(sourceFolder, @"Patch.wxs"),
220 "-d", "V=" + defineV,
221 "-bindpath", Path.Combine(baseFolder, "bin"),
222 "-intermediateFolder", Path.Combine(baseFolder, "obj"),
223 "-o", outputPath
224 };
225
226 foreach (var additionaBindPath in bindpaths ?? Enumerable.Empty<string>())
227 {
228 args.Add("-bindpath");
229 args.Add(additionaBindPath);
230 }
231
232 var result = WixRunner.Execute(args.ToArray());
233
234 result.AssertSuccess();
235
236 return Path.ChangeExtension(outputPath, ".wixpdb");
237 }
238
239 private static string BuildBundle(string outputName, string sourceFolder, string baseFolder)
240 {
241 var outputPath = Path.Combine(baseFolder, Path.Combine("bin", outputName));
242
243 var result = WixRunner.Execute(new[]
244 {
245 "build",
246 Path.Combine(sourceFolder, @"Bundle.wxs"),
247 Path.Combine(sourceFolder, "..", "..", "BundleWithPackageGroupRef", "Bundle.wxs"),
248 "-bindpath", Path.Combine(sourceFolder, "..", "..", "SimpleBundle", "data"),
249 "-bindpath", Path.Combine(baseFolder, "bin"),
250 "-intermediateFolder", Path.Combine(baseFolder, "obj"),
251 "-o", outputPath
252 });
253
254 result.AssertSuccess();
255
256 return Path.ChangeExtension(outputPath, ".wixpdb");
257 }
258
259 private static XDocument GetExtractPatchXml(string path)
260 {
261 var buffer = new StringBuilder(65535);
262 var size = buffer.Capacity;
263
264 var er = MsiExtractPatchXMLData(path, 0, buffer, ref size);
265 if (er != 0)
266 {
267 throw new Win32Exception(er);
268 }
269
270 return XDocument.Parse(buffer.ToString());
271 }
272
273 [DllImport("msi.dll", EntryPoint = "MsiExtractPatchXMLDataW", CharSet = CharSet.Unicode, ExactSpelling = true)]
274 private static extern int MsiExtractPatchXMLData(string szPatchPath, int dwReserved, StringBuilder szXMLData, ref int pcchXMLData);
275
276 [DllImport("msi.dll", EntryPoint = "MsiApplyPatchW", CharSet = CharSet.Unicode, ExactSpelling = true)]
277 private static extern int MsiApplyPatch(string szPatchPackage, string szInstallPackage, int eInstallType, string szCommandLine);
278 }
279}