Discard the correct RollbackBoundary.
Sean Hall committed
Apr 13, 2022 at 10:12 UTC
17d4ba9d93814cffa688e9152d11a340f9e0f754
5 files changed
+135
-11
src/wix/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs
+2
-4
@@ -94,6 +94,7 @@ namespace WixToolset.Core.Burn.Bind
94
case SymbolDefinitionType.WixBundleVariable:
95
case SymbolDefinitionType.WixBuildInfo:
96
case SymbolDefinitionType.WixChain:
97
+ case SymbolDefinitionType.WixChainItem:
98
case SymbolDefinitionType.WixComponentSearch:
99
case SymbolDefinitionType.WixDependencyProvider:
100
case SymbolDefinitionType.WixFileSearch:
@@ -114,10 +115,7 @@ namespace WixToolset.Core.Burn.Bind
115
case SymbolDefinitionType.WixVariable:
116
break;
117
117
- // Symbols to investigate:
118
- case SymbolDefinitionType.WixChainItem:
119
- break;
120
-
118
+ // All other symbols need to be processed.
119
case SymbolDefinitionType.WixBundleCustomData:
120
unknownSymbol = !this.IndexBundleCustomDataSymbol((WixBundleCustomDataSymbol)symbol, customDataById);
121
break;
src/wix/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs
+6
-7
@@ -94,15 +94,14 @@ namespace WixToolset.Core.Burn.Bundles
94
{
95
// Discard the next rollback boundary if we have a previously defined boundary.
96
var nextRollbackBoundary = boundariesById[groupSymbol.ChildId];
97
- if (null != pendingRollbackBoundary)
97
+ if (null != pendingRollbackBoundary && pendingRollbackBoundary.Id.Id != BurnConstants.BundleDefaultBoundaryId)
98
{
99
- if (pendingRollbackBoundary.Id.Id != BurnConstants.BundleDefaultBoundaryId)
100
- {
101
- this.Messaging.Write(WarningMessages.DiscardedRollbackBoundary(nextRollbackBoundary.SourceLineNumbers, nextRollbackBoundary.Id.Id));
102
- }
99
+ this.Messaging.Write(WarningMessages.DiscardedRollbackBoundary(nextRollbackBoundary.SourceLineNumbers, nextRollbackBoundary.Id.Id));
100
+ }
101
+ else
102
+ {
103
+ lastRollbackBoundary = pendingRollbackBoundary = nextRollbackBoundary;
104
}
104
-
105
- lastRollbackBoundary = pendingRollbackBoundary = nextRollbackBoundary;
105
}
106
}
107
}
src/wix/test/WixToolsetTest.CoreIntegration/RollbackBoundaryFixture.cs
+105
@@ -2,7 +2,10 @@
2
3
namespace WixToolsetTest.CoreIntegration
4
{
5
+ using System.Collections.Generic;
6
using System.IO;
7
+ using System.Linq;
8
+ using System.Xml;
9
using WixBuildTools.TestSupport;
10
using WixToolset.Core.TestPackage;
11
using Xunit;
@@ -37,5 +40,107 @@ namespace WixToolsetTest.CoreIntegration
40
}
41
}
42
43
+ [Fact]
44
+ public void CannotHaveRollbackBoundaryAndChainPackageWithSameId()
45
+ {
46
+ var folder = TestData.Get(@"TestData");
47
+
48
+ using (var fs = new DisposableFileSystem())
49
+ {
50
+ var baseFolder = fs.GetFolder();
51
+ var intermediateFolder = Path.Combine(baseFolder, "obj");
52
+ var exePath = Path.Combine(baseFolder, @"bin\test.exe");
53
+
54
+ var result = WixRunner.Execute(new[]
55
+ {
56
+ "build",
57
+ Path.Combine(folder, "RollbackBoundary", "SharedIdWithPackage.wxs"),
58
+ Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
59
+ Path.Combine(folder, "BundleWithPackageGroupRef", "MinimalPackageGroup.wxs"),
60
+ "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
61
+ "-intermediateFolder", intermediateFolder,
62
+ "-o", exePath,
63
+ });
64
+
65
+ Assert.Equal(92, result.ExitCode);
66
+
67
+ WixAssert.CompareLineByLine(new[]
68
+ {
69
+ "Duplicate symbol 'WixChainItem:collision' found. This typically means that an Id is duplicated. Access modifiers (internal, protected, private) cannot prevent these conflicts. Ensure all your identifiers of a given type (File, Component, Feature) are unique.",
70
+ "Location of symbol related to previous error.",
71
+ }, result.Messages.Select(m => m.ToString()).ToArray());
72
+
73
+ Assert.False(File.Exists(exePath));
74
+ }
75
+ }
76
+
77
+ [Fact]
78
+ public void DiscardsConsecutiveRollbackBoundaries()
79
+ {
80
+ var folder = TestData.Get(@"TestData");
81
+
82
+ using (var fs = new DisposableFileSystem())
83
+ {
84
+ var baseFolder = fs.GetFolder();
85
+ var intermediateFolder = Path.Combine(baseFolder, "obj");
86
+ var exePath = Path.Combine(baseFolder, @"bin\test.exe");
87
+ var baFolderPath = Path.Combine(baseFolder, "ba");
88
+ var extractFolderPath = Path.Combine(baseFolder, "extract");
89
+
90
+ var result = WixRunner.Execute(false, new[]
91
+ {
92
+ "build",
93
+ Path.Combine(folder, "RollbackBoundary", "ConsecutiveRollbackBoundaries.wxs"),
94
+ Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
95
+ Path.Combine(folder, "BundleWithPackageGroupRef", "MinimalPackageGroup.wxs"),
96
+ "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
97
+ "-intermediateFolder", intermediateFolder,
98
+ "-o", exePath,
99
+ });
100
+
101
+ result.AssertSuccess();
102
+
103
+ WixAssert.CompareLineByLine(new[]
104
+ {
105
+ "The RollbackBoundary 'Second' was discarded because it was not followed by a package. Without a package the rollback boundary doesn't do anything. Verify that the RollbackBoundary element is not followed by another RollbackBoundary and that the element is not at the end of the chain.",
106
+ }, result.Messages.Select(m => m.ToString()).ToArray());
107
+
108
+ Assert.True(File.Exists(exePath));
109
+
110
+ var extractResult = BundleExtractor.ExtractBAContainer(null, exePath, baFolderPath, extractFolderPath);
111
+ extractResult.AssertSuccess();
112
+
113
+ var rollbackBoundaries = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:RollbackBoundary")
114
+ .Cast<XmlElement>()
115
+ .Select(e => e.GetTestXml())
116
+ .ToArray();
117
+ WixAssert.CompareLineByLine(new string[]
118
+ {
119
+ "<RollbackBoundary Id='First' Vital='yes' Transaction='no' />",
120
+ }, rollbackBoundaries);
121
+
122
+ var ignoreAttributesByElementName = new Dictionary<string, List<string>>
123
+ {
124
+ { "MsiPackage", new List<string> { "Size" } },
125
+ };
126
+ var chainPackages = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Chain/*")
127
+ .Cast<XmlElement>()
128
+ .Select(e => e.GetTestXml(ignoreAttributesByElementName))
129
+ .ToArray();
130
+ WixAssert.CompareLineByLine(new string[]
131
+ {
132
+ "<MsiPackage Id='test.msi' Cache='keep' CacheId='{040011E1-F84C-4927-AD62-50A5EC19CA32}v1.0.0.0' InstallSize='34' Size='*' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='First' RollbackBoundaryBackward='First' LogPathVariable='WixBundleLog_test.msi' RollbackLogPathVariable='WixBundleRollbackLog_test.msi' ProductCode='{040011E1-F84C-4927-AD62-50A5EC19CA32}' Language='1033' Version='1.0.0.0' UpgradeCode='{047730A5-30FE-4A62-A520-DA9381B8226A}'>" +
133
+ "<MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />" +
134
+ "<MsiProperty Id='MSIFASTINSTALL' Value='7' />" +
135
+ "<Provides Key='{040011E1-F84C-4927-AD62-50A5EC19CA32}_v1.0.0.0' Version='1.0.0.0' DisplayName='MsiPackage' />" +
136
+ "<RelatedPackage Id='{047730A5-30FE-4A62-A520-DA9381B8226A}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" +
137
+ "<RelatedPackage Id='{047730A5-30FE-4A62-A520-DA9381B8226A}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" +
138
+ "<PayloadRef Id='test.msi' />" +
139
+ "<PayloadRef Id='fhuZsOcBDTuIX8rF96kswqI6SnuI' />" +
140
+ "<PayloadRef Id='faf_OZ741BG7SJ6ZkcIvivZ2Yzo8' />" +
141
+ "</MsiPackage>",
142
+ }, chainPackages);
143
+ }
144
+ }
145
}
146
}
src/wix/test/WixToolsetTest.CoreIntegration/TestData/RollbackBoundary/ConsecutiveRollbackBoundaries.wxs
new
+13
@@ -0,0 +1,13 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3
+ <Fragment>
4
+ <PackageGroup Id="PreBundlePackages">
5
+ <RollbackBoundary Id="First" />
6
+ </PackageGroup>
7
+ <PackageGroup Id="BundlePackages">
8
+ <PackageGroupRef Id="PreBundlePackages" />
9
+ <RollbackBoundary Id="Second" />
10
+ <MsiPackage SourceFile="test.msi" />
11
+ </PackageGroup>
12
+ </Fragment>
13
+</Wix>
src/wix/test/WixToolsetTest.CoreIntegration/TestData/RollbackBoundary/SharedIdWithPackage.wxs
new
+9
@@ -0,0 +1,9 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3
+ <Fragment>
4
+ <PackageGroup Id="BundlePackages">
5
+ <RollbackBoundary Id="collision" />
6
+ <MsiPackage Id="collision" SourceFile="test.msi" />
7
+ </PackageGroup>
8
+ </Fragment>
9
+</Wix>