diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-01-01 14:02:51 -0600 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-01-03 16:20:18 -0600 |
commit | 36b1a2ce73b394ca3ed7490a1392320e2f401cbd (patch) | |
tree | a63b4e6150e7abd30dbe3db5983304d9c604ab77 | |
parent | d45c8da71cd9eecdbb314d04754f4316cadeba6f (diff) | |
download | wix-36b1a2ce73b394ca3ed7490a1392320e2f401cbd.tar.gz wix-36b1a2ce73b394ca3ed7490a1392320e2f401cbd.tar.bz2 wix-36b1a2ce73b394ca3ed7490a1392320e2f401cbd.zip |
Create failing test for issue 6309.
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 | |||
3 | namespace 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 | } | ||