aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-01-01 14:02:51 -0600
committerSean Hall <r.sean.hall@gmail.com>2021-01-03 16:20:18 -0600
commit36b1a2ce73b394ca3ed7490a1392320e2f401cbd (patch)
treea63b4e6150e7abd30dbe3db5983304d9c604ab77
parentd45c8da71cd9eecdbb314d04754f4316cadeba6f (diff)
downloadwix-36b1a2ce73b394ca3ed7490a1392320e2f401cbd.tar.gz
wix-36b1a2ce73b394ca3ed7490a1392320e2f401cbd.tar.bz2
wix-36b1a2ce73b394ca3ed7490a1392320e2f401cbd.zip
Create failing test for issue 6309.
-rw-r--r--src/TestData/RollbackBoundary/BundleA/BundleA.wixproj15
-rw-r--r--src/TestData/RollbackBoundary/BundleA/BundleA.wxi21
-rw-r--r--src/TestData/RollbackBoundary/BundleA/BundleA.wxs16
-rw-r--r--src/TestData/RollbackBoundary/PackageA/PackageA.wixproj9
-rw-r--r--src/TestData/RollbackBoundary/PackageB/PackageB.wixproj9
-rw-r--r--src/TestData/RollbackBoundary/PackageC/PackageC.wixproj9
-rw-r--r--src/TestData/RollbackBoundary/PackageF/PackageF.wixproj12
-rw-r--r--src/WixToolsetTest.BurnE2E/BundleInstaller.cs56
-rw-r--r--src/WixToolsetTest.BurnE2E/RollbackBoundaryTests.cs52
9 files changed, 186 insertions, 13 deletions
diff --git a/src/TestData/RollbackBoundary/BundleA/BundleA.wixproj b/src/TestData/RollbackBoundary/BundleA/BundleA.wixproj
new file mode 100644
index 00000000..96f7aa31
--- /dev/null
+++ b/src/TestData/RollbackBoundary/BundleA/BundleA.wixproj
@@ -0,0 +1,15 @@
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<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 </PropertyGroup>
6 <ItemGroup>
7 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
8 <ProjectReference Include="..\PackageB\PackageB.wixproj" />
9 <ProjectReference Include="..\PackageC\PackageC.wixproj" />
10 <ProjectReference Include="..\PackageF\PackageF.wixproj" />
11 </ItemGroup>
12 <ItemGroup>
13 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.77" />
14 </ItemGroup>
15</Project> \ No newline at end of file
diff --git a/src/TestData/RollbackBoundary/BundleA/BundleA.wxi b/src/TestData/RollbackBoundary/BundleA/BundleA.wxi
new file mode 100644
index 00000000..145073b5
--- /dev/null
+++ b/src/TestData/RollbackBoundary/BundleA/BundleA.wxi
@@ -0,0 +1,21 @@
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<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Include xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
8 <Bundle Name="~$(var.TestGroupName) - Bundle A" Version="$(var.Version)" UpgradeCode="{E8426C86-D5E4-45FA-B09D-789DC7E5E00A}" Compressed="yes">
9 <Log Prefix="~$(var.TestGroupName)_BundleA" />
10
11 <Variable Name="TestGroupName" Value="$(var.TestGroupName)" />
12
13 <BootstrapperApplication>
14 <bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkLicense" />
15 </BootstrapperApplication>
16
17 <Chain>
18 <PackageGroupRef Id="BundlePackages" />
19 </Chain>
20 </Bundle>
21</Include>
diff --git a/src/TestData/RollbackBoundary/BundleA/BundleA.wxs b/src/TestData/RollbackBoundary/BundleA/BundleA.wxs
new file mode 100644
index 00000000..251b1863
--- /dev/null
+++ b/src/TestData/RollbackBoundary/BundleA/BundleA.wxs
@@ -0,0 +1,16 @@
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
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <?include BundleA.wxi ?>
6 <Fragment>
7 <PackageGroup Id="BundlePackages">
8 <MsiPackage Id="PackageC" SourceFile="$(var.PackageC.TargetPath)" Permanent="yes" /> <!-- TODO: this is a workaround for inability to specify RollbackBoundary as first package, remove when this is fixed -->
9 <RollbackBoundary Id="nonvital" Vital="no" />
10 <MsiPackage Id="PackageF" SourceFile="$(var.PackageF.TargetPath)" />
11 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" Permanent="yes" />
12 <RollbackBoundary />
13 <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" Permanent="yes" />
14 </PackageGroup>
15 </Fragment>
16</Wix>
diff --git a/src/TestData/RollbackBoundary/PackageA/PackageA.wixproj b/src/TestData/RollbackBoundary/PackageA/PackageA.wixproj
new file mode 100644
index 00000000..25d9e279
--- /dev/null
+++ b/src/TestData/RollbackBoundary/PackageA/PackageA.wixproj
@@ -0,0 +1,9 @@
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<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{14A06CEA-CC9E-478F-AD20-5C9624827090}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/TestData/RollbackBoundary/PackageB/PackageB.wixproj b/src/TestData/RollbackBoundary/PackageB/PackageB.wixproj
new file mode 100644
index 00000000..2dc4f3a6
--- /dev/null
+++ b/src/TestData/RollbackBoundary/PackageB/PackageB.wixproj
@@ -0,0 +1,9 @@
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<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{C0B6E75E-4378-4589-B3C5-A23FFA39F59B}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/TestData/RollbackBoundary/PackageC/PackageC.wixproj b/src/TestData/RollbackBoundary/PackageC/PackageC.wixproj
new file mode 100644
index 00000000..a4b5134b
--- /dev/null
+++ b/src/TestData/RollbackBoundary/PackageC/PackageC.wixproj
@@ -0,0 +1,9 @@
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<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{1C977E8F-4E79-4E3B-A5B1-C4B0BE774041}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/TestData/RollbackBoundary/PackageF/PackageF.wixproj b/src/TestData/RollbackBoundary/PackageF/PackageF.wixproj
new file mode 100644
index 00000000..d51fab1f
--- /dev/null
+++ b/src/TestData/RollbackBoundary/PackageF/PackageF.wixproj
@@ -0,0 +1,12 @@
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<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{E348D377-E5E7-44B0-897E-5DC8D401BF80}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\PackageFail.wxs" Link="PackageFail.wxs" />
8 </ItemGroup>
9 <ItemGroup>
10 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.66" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/WixToolsetTest.BurnE2E/BundleInstaller.cs b/src/WixToolsetTest.BurnE2E/BundleInstaller.cs
index c85646bb..5ce993f3 100644
--- a/src/WixToolsetTest.BurnE2E/BundleInstaller.cs
+++ b/src/WixToolsetTest.BurnE2E/BundleInstaller.cs
@@ -15,6 +15,8 @@ namespace WixToolsetTest.BurnE2E
15 { 15 {
16 public const string BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY = "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; 16 public const string BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY = "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
17 public const string BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH = "BundleCachePath"; 17 public const string BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH = "BundleCachePath";
18 public const string FULL_BURN_POLICY_REGISTRY_PATH = "SOFTWARE\\WOW6432Node\\Policies\\WiX\\Burn";
19 public const string PACKAGE_CACHE_FOLDER_NAME = "Package Cache";
18 20
19 public BundleInstaller(WixTestContext testContext, string name) 21 public BundleInstaller(WixTestContext testContext, string name)
20 { 22 {
@@ -28,6 +30,8 @@ namespace WixToolsetTest.BurnE2E
28 30
29 public string BundlePdb { get; } 31 public string BundlePdb { get; }
30 32
33 private WixBundleSymbol BundleSymbol { get; set; }
34
31 public string TestGroupName { get; } 35 public string TestGroupName { get; }
32 36
33 public string TestName { get; } 37 public string TestName { get; }
@@ -142,37 +146,63 @@ namespace WixToolsetTest.BurnE2E
142 return logFile; 146 return logFile;
143 } 147 }
144 148
149 private WixBundleSymbol GetBundleSymbol()
150 {
151 if (this.BundleSymbol == null)
152 {
153 using var wixOutput = WixOutput.Read(this.BundlePdb);
154 var intermediate = Intermediate.Load(wixOutput);
155 var section = intermediate.Sections.Single();
156 this.BundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
157 }
158
159 return this.BundleSymbol;
160 }
161
162 public string GetExpectedCachedBundlePath()
163 {
164 var bundleSymbol = this.GetBundleSymbol();
165
166 using var policyKey = Registry.LocalMachine.OpenSubKey(FULL_BURN_POLICY_REGISTRY_PATH);
167 var redirectedCachePath = policyKey?.GetValue("PackageCache") as string;
168 var cachePath = redirectedCachePath ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), PACKAGE_CACHE_FOLDER_NAME);
169 return Path.Combine(cachePath, bundleSymbol.BundleId, Path.GetFileName(this.Bundle));
170 }
171
145 public string VerifyRegisteredAndInPackageCache() 172 public string VerifyRegisteredAndInPackageCache()
146 { 173 {
147 using var wixOutput = WixOutput.Read(this.BundlePdb); 174 var bundleSymbol = this.GetBundleSymbol();
148 var intermediate = Intermediate.Load(wixOutput);
149 var section = intermediate.Sections.Single();
150 var bundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
151 var bundleId = bundleSymbol.BundleId; 175 var bundleId = bundleSymbol.BundleId;
152 var registrationKeyPath = $"{BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY}\\{bundleId}"; 176 var registrationKeyPath = $"{BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY}\\{bundleId}";
153 177
154 using var testKey = Registry.LocalMachine.OpenSubKey(registrationKeyPath); 178 using var registrationKey = Registry.LocalMachine.OpenSubKey(registrationKeyPath);
155 Assert.NotNull(testKey); 179 Assert.NotNull(registrationKey);
156 180
157 var cachePathValue = testKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH); 181 var cachePathValue = registrationKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH);
158 Assert.NotNull(cachePathValue); 182 Assert.NotNull(cachePathValue);
159 var cachePath = Assert.IsType<string>(cachePathValue); 183 var cachePath = Assert.IsType<string>(cachePathValue);
160 Assert.True(File.Exists(cachePath)); 184 Assert.True(File.Exists(cachePath));
161 185
186 var expectedCachePath = this.GetExpectedCachedBundlePath();
187 Assert.Equal(expectedCachePath, cachePath, StringComparer.OrdinalIgnoreCase);
188
162 return cachePath; 189 return cachePath;
163 } 190 }
164 191
192 public void VerifyUnregisteredAndRemovedFromPackageCache()
193 {
194 var cachedBundlePath = this.GetExpectedCachedBundlePath();
195 this.VerifyUnregisteredAndRemovedFromPackageCache(cachedBundlePath);
196 }
197
165 public void VerifyUnregisteredAndRemovedFromPackageCache(string cachedBundlePath) 198 public void VerifyUnregisteredAndRemovedFromPackageCache(string cachedBundlePath)
166 { 199 {
167 using var wixOutput = WixOutput.Read(this.BundlePdb); 200 var bundleSymbol = this.GetBundleSymbol();
168 var intermediate = Intermediate.Load(wixOutput);
169 var section = intermediate.Sections.Single();
170 var bundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
171 var bundleId = bundleSymbol.BundleId; 201 var bundleId = bundleSymbol.BundleId;
172 var registrationKeyPath = $"{BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY}\\{bundleId}"; 202 var registrationKeyPath = $"{BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY}\\{bundleId}";
173 203
174 using var testKey = Registry.LocalMachine.OpenSubKey(registrationKeyPath); 204 using var registrationKey = Registry.LocalMachine.OpenSubKey(registrationKeyPath);
175 Assert.Null(testKey); 205 Assert.Null(registrationKey);
176 206
177 Assert.False(File.Exists(cachedBundlePath)); 207 Assert.False(File.Exists(cachedBundlePath));
178 } 208 }
diff --git a/src/WixToolsetTest.BurnE2E/RollbackBoundaryTests.cs b/src/WixToolsetTest.BurnE2E/RollbackBoundaryTests.cs
new file mode 100644
index 00000000..1ae81b49
--- /dev/null
+++ b/src/WixToolsetTest.BurnE2E/RollbackBoundaryTests.cs
@@ -0,0 +1,52 @@
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.BurnE2E
4{
5 using System;
6 using System.IO;
7 using Xunit;
8 using Xunit.Abstractions;
9
10 public class RollbackBoundaryTests : BurnE2ETests
11 {
12 public RollbackBoundaryTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper, "RollbackBoundary") { }
13
14 /// <summary>
15 /// Installs 1 bundle:
16 /// chain - non-vital rollback boundary, package F, package A, vital rollback boundary, package B
17 /// package F fails
18 /// package A and B are permanent
19 /// Execution is supposed to be:
20 /// package F (fails)
21 /// rollback to non-vital rollback boundary which ignores the error and skips over package A
22 /// install package B
23 /// unregister since no non-permanent packages should be installed or cached.
24 /// </summary>
25 [Fact]
26 public void NonVitalRollbackBoundarySkipsToNextRollbackBoundary()
27 {
28 var packageA = this.CreatePackageInstaller("PackageA");
29 var packageB = this.CreatePackageInstaller("PackageB");
30 this.CreatePackageInstaller("PackageC");
31 this.CreatePackageInstaller("PackageF");
32
33 var bundleA = this.CreateBundleInstaller("BundleA");
34
35 var packageASourceCodeInstalled = packageA.GetInstalledFilePath("Package.wxs");
36 var packageBSourceCodeInstalled = packageB.GetInstalledFilePath("Package.wxs");
37
38 // Source file should *not* be installed
39 Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}");
40 Assert.False(File.Exists(packageBSourceCodeInstalled), $"Package B payload should not be there on test start: {packageBSourceCodeInstalled}");
41
42 bundleA.Install();
43
44 // No non-permanent packages should have ended up installed or cached so it should have unregistered.
45 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
46
47 // Only PackageB source file should be installed
48 Assert.True(File.Exists(packageBSourceCodeInstalled), String.Concat("Should have found Package B payload installed at: ", packageBSourceCodeInstalled));
49 Assert.False(File.Exists(packageASourceCodeInstalled), String.Concat("Should not have found Package A payload installed at: ", packageASourceCodeInstalled));
50 }
51 }
52}