From 856b54b5fd60767640a50339d8203b8147415582 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 5 Jan 2022 21:51:00 -0600 Subject: [PATCH] Always run upgrade related bundles last. #5128 --- src/Directory.Build.props | 1 + src/burn/engine/registration.cpp | 2 + src/burn/engine/relatedbundle.cpp | 55 ++++ src/burn/engine/relatedbundle.h | 3 + src/test/burn/BurnE2ETests.sln | 42 ++- src/test/burn/Directory.wixproj.props | 1 + .../ForTestingUseOnly.wixext.csproj | 15 ++ .../ForTestingUseOnlyBurnBackendExtension.cs | 43 +++ .../ForTestingUseOnlyCompiler.cs | 77 ++++++ .../ForTestingUseOnlyExtensionData.cs | 16 ++ .../ForTestingUseOnlyExtensionFactory.cs | 18 ++ .../Symbols/ForTestingUseOnlyBundleSymbol.cs | 47 ++++ .../ForTestingUseOnlySymbolDefinitions.cs | 43 +++ .../DependencyTests/BundleF/BundleF.props | 10 + .../DependencyTests/BundleF/BundleF.wixproj | 8 +- .../DependencyTests/BundleF/BundleF.wxs | 3 +- .../BundleF_AddOnA/BundleF_AddOnA.wixproj | 3 + .../{BundleF_AddOn.wxs => BundleF_AddOnA.wxs} | 3 +- .../BundleF_AddOnB/BundleF_AddOnB.wixproj | 4 +- .../BundleF_AddOnB/BundleF_AddOnB.wxs | 23 ++ .../BundleFv2/BundleFv2.wixproj | 17 ++ .../DependencyTests/BundleFv2/BundleFv2.wxs | 12 + .../WixToolsetTest.BurnE2E/BurnE2ETests.cs | 7 + .../WixToolsetTest.BurnE2E/DependencyTests.cs | 253 ++++++++++++------ 24 files changed, 602 insertions(+), 104 deletions(-) create mode 100644 src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnly.wixext.csproj create mode 100644 src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyBurnBackendExtension.cs create mode 100644 src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyCompiler.cs create mode 100644 src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyExtensionData.cs create mode 100644 src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyExtensionFactory.cs create mode 100644 src/test/burn/ForTestingUseOnlyExtension/Symbols/ForTestingUseOnlyBundleSymbol.cs create mode 100644 src/test/burn/ForTestingUseOnlyExtension/Symbols/ForTestingUseOnlySymbolDefinitions.cs create mode 100644 src/test/burn/TestData/DependencyTests/BundleF/BundleF.props rename src/test/burn/TestData/DependencyTests/BundleF_AddOnA/{BundleF_AddOn.wxs => BundleF_AddOnA.wxs} (86%) create mode 100644 src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wxs create mode 100644 src/test/burn/TestData/DependencyTests/BundleFv2/BundleFv2.wixproj create mode 100644 src/test/burn/TestData/DependencyTests/BundleFv2/BundleFv2.wxs diff --git a/src/Directory.Build.props b/src/Directory.Build.props index da099c3d1..d068e9e88 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -6,6 +6,7 @@ Debug false true + $(NoWarn);MSB3026 $(MSBuildProjectName) $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\build\)) diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp index 9cc4b199c..ffeb39d15 100644 --- a/src/burn/engine/registration.cpp +++ b/src/burn/engine/registration.cpp @@ -585,6 +585,8 @@ extern "C" HRESULT RegistrationDetectRelatedBundles( hr = RelatedBundlesInitializeForScope(FALSE, pRegistration, &pRegistration->relatedBundles); ExitOnFailure(hr, "Failed to initialize per-user related bundles."); + RelatedBundlesSort(&pRegistration->relatedBundles); + LExit: return hr; } diff --git a/src/burn/engine/relatedbundle.cpp b/src/burn/engine/relatedbundle.cpp index e2380aabd..1eafef076 100644 --- a/src/burn/engine/relatedbundle.cpp +++ b/src/burn/engine/relatedbundle.cpp @@ -4,6 +4,11 @@ // internal function declarations +static __callback int __cdecl CompareRelatedBundles( + __in void* pvContext, + __in const void* pvLeft, + __in const void* pvRight + ); static HRESULT LoadIfRelatedBundle( __in BOOL fPerMachine, __in HKEY hkUninstallKey, @@ -128,9 +133,59 @@ extern "C" HRESULT RelatedBundleFindById( return hr; } +extern "C" void RelatedBundlesSort( + __in BURN_RELATED_BUNDLES* pRelatedBundles + ) +{ + qsort_s(pRelatedBundles->rgRelatedBundles, pRelatedBundles->cRelatedBundles, sizeof(BURN_RELATED_BUNDLE), CompareRelatedBundles, NULL); +} + // internal helper functions +static __callback int __cdecl CompareRelatedBundles( + __in void* /*pvContext*/, + __in const void* pvLeft, + __in const void* pvRight + ) +{ + int ret = 0; + const BURN_RELATED_BUNDLE* pBundleLeft = static_cast(pvLeft); + const BURN_RELATED_BUNDLE* pBundleRight = static_cast(pvRight); + + // Sort by relation type, then version, then bundle id. + if (pBundleLeft->relationType != pBundleRight->relationType) + { + // Upgrade bundles last, everything else according to the enum. + if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleLeft->relationType) + { + ret = 1; + } + else if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleRight->relationType) + { + ret = -1; + } + else if (pBundleLeft->relationType < pBundleRight->relationType) + { + ret = -1; + } + else + { + ret = 1; + } + } + else + { + VerCompareParsedVersions(pBundleLeft->pVersion, pBundleRight->pVersion, &ret); + if (0 == ret) + { + ret = ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pBundleLeft->package.sczId, -1, pBundleRight->package.sczId, -1) - 2; + } + } + + return ret; +} + static HRESULT LoadIfRelatedBundle( __in BOOL fPerMachine, __in HKEY hkUninstallKey, diff --git a/src/burn/engine/relatedbundle.h b/src/burn/engine/relatedbundle.h index 0113c8eeb..be039421b 100644 --- a/src/burn/engine/relatedbundle.h +++ b/src/burn/engine/relatedbundle.h @@ -19,6 +19,9 @@ HRESULT RelatedBundleFindById( __in_z LPCWSTR wzId, __out BURN_RELATED_BUNDLE** ppRelatedBundle ); +void RelatedBundlesSort( + __in BURN_RELATED_BUNDLES* pRelatedBundles + ); #if defined(__cplusplus) } diff --git a/src/test/burn/BurnE2ETests.sln b/src/test/burn/BurnE2ETests.sln index 5d69855cb..98cd3575d 100644 --- a/src/test/burn/BurnE2ETests.sln +++ b/src/test/burn/BurnE2ETests.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29503.13 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31919.166 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestBA", "TestBA\TestBA.csproj", "{04022D35-6D75-49D0-91D2-4208E09DBA6D}" EndProject @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.WixBA", "WixTool EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.BurnE2E", "WixToolsetTest.BurnE2E\WixToolsetTest.BurnE2E.csproj", "{FED9D707-E5C3-4867-87B0-FABDB5EB0823}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ForTestingUseOnly.wixext", "ForTestingUseOnlyExtension\ForTestingUseOnly.wixext.csproj", "{0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -59,18 +61,6 @@ Global {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Release|x64.Build.0 = Release|Any CPU {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Release|x86.ActiveCfg = Release|Any CPU {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Release|x86.Build.0 = Release|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x64.ActiveCfg = Debug|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x64.Build.0 = Debug|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x86.ActiveCfg = Debug|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x86.Build.0 = Debug|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|Any CPU.Build.0 = Release|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x64.ActiveCfg = Release|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x64.Build.0 = Release|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x86.ActiveCfg = Release|Any CPU - {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x86.Build.0 = Release|Any CPU {7C27518B-84AD-4679-8EF4-29DF552CF1AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7C27518B-84AD-4679-8EF4-29DF552CF1AC}.Debug|Any CPU.Build.0 = Debug|Any CPU {7C27518B-84AD-4679-8EF4-29DF552CF1AC}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -83,6 +73,30 @@ Global {7C27518B-84AD-4679-8EF4-29DF552CF1AC}.Release|x64.Build.0 = Release|Any CPU {7C27518B-84AD-4679-8EF4-29DF552CF1AC}.Release|x86.ActiveCfg = Release|Any CPU {7C27518B-84AD-4679-8EF4-29DF552CF1AC}.Release|x86.Build.0 = Release|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x64.ActiveCfg = Debug|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x64.Build.0 = Debug|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x86.ActiveCfg = Debug|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x86.Build.0 = Debug|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|Any CPU.Build.0 = Release|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x64.ActiveCfg = Release|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x64.Build.0 = Release|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x86.ActiveCfg = Release|Any CPU + {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x86.Build.0 = Release|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Debug|x64.ActiveCfg = Debug|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Debug|x64.Build.0 = Debug|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Debug|x86.ActiveCfg = Debug|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Debug|x86.Build.0 = Debug|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Release|Any CPU.Build.0 = Release|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Release|x64.ActiveCfg = Release|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Release|x64.Build.0 = Release|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Release|x86.ActiveCfg = Release|Any CPU + {0037E6A3-45C6-4AB6-BC8C-1CB0C145E992}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/test/burn/Directory.wixproj.props b/src/test/burn/Directory.wixproj.props index 06cf5b1df..af5ef1961 100644 --- a/src/test/burn/Directory.wixproj.props +++ b/src/test/burn/Directory.wixproj.props @@ -7,5 +7,6 @@ None -wx 1154;$(SuppressSpecificWarnings) + $(BaseOutputPath)$(Configuration)\netstandard2.0\ForTestingUseOnly.wixext.dll diff --git a/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnly.wixext.csproj b/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnly.wixext.csproj new file mode 100644 index 000000000..c3861a962 --- /dev/null +++ b/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnly.wixext.csproj @@ -0,0 +1,15 @@ + + + + + + netstandard2.0 + ForTestingUseOnly + embedded + true + + + + + + diff --git a/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyBurnBackendExtension.cs b/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyBurnBackendExtension.cs new file mode 100644 index 000000000..fff232743 --- /dev/null +++ b/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyBurnBackendExtension.cs @@ -0,0 +1,43 @@ +// 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. + +namespace ForTestingUseOnly +{ + using System.Collections.Generic; + using System.Linq; + using ForTestingUseOnly.Symbols; + using WixToolset.Data; + using WixToolset.Data.Symbols; + using WixToolset.Extensibility; + + /// + /// Extension for doing completely unsupported things in the name of testing. + /// + public class ForTestingUseOnlyBurnBackendExtension : BaseBurnBackendBinderExtension + { + private static readonly IntermediateSymbolDefinition[] BurnSymbolDefinitions = + { + ForTestingUseOnlySymbolDefinitions.ForTestingUseOnlyBundle, + }; + + protected override IReadOnlyCollection SymbolDefinitions => BurnSymbolDefinitions; + + public override void SymbolsFinalized(IntermediateSection section) + { + base.SymbolsFinalized(section); + + this.FinalizeBundleSymbol(section); + } + + private void FinalizeBundleSymbol(IntermediateSection section) + { + var forTestingUseOnlyBundleSymbol = section.Symbols.OfType().SingleOrDefault(); + if (null == forTestingUseOnlyBundleSymbol) + { + return; + } + + var bundleSymbol = section.Symbols.OfType().Single(); + bundleSymbol.ProviderKey = bundleSymbol.BundleId = forTestingUseOnlyBundleSymbol.BundleId; + } + } +} diff --git a/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyCompiler.cs b/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyCompiler.cs new file mode 100644 index 000000000..4963c941d --- /dev/null +++ b/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyCompiler.cs @@ -0,0 +1,77 @@ +// 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. + +namespace ForTestingUseOnly +{ + using System; + using System.Collections.Generic; + using System.Xml.Linq; + using ForTestingUseOnly.Symbols; + using WixToolset.Data; + using WixToolset.Extensibility; + + /// + /// Extension for doing completely unsupported things in the name of testing. + /// + public sealed class ForTestingUseOnlyCompiler : BaseCompilerExtension + { + public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/fortestinguseonly"; + + public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary context) + { + switch (element.Name.LocalName) + { + case "ForTestingUseOnlyBundle": + this.ParseForTestingUseOnlyBundleElement(intermediate, section, element); + break; + default: + this.ParseHelper.UnexpectedElement(parentElement, element); + break; + } + } + + private void ParseForTestingUseOnlyBundleElement(Intermediate intermediate, IntermediateSection section, XElement element) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + string bundleId = null; + + foreach (var attrib in element.Attributes()) + { + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) + { + switch (attrib.Name.LocalName) + { + case "Id": + bundleId = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == bundleId) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id")); + } + else + { + bundleId = Guid.Parse(bundleId).ToString("B").ToUpperInvariant(); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + if (!this.Messaging.EncounteredError) + { + section.AddSymbol(new ForTestingUseOnlyBundleSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "ForTestingUseOnlyBundle")) + { + BundleId = bundleId, + }); + } + } + } +} diff --git a/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyExtensionData.cs b/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyExtensionData.cs new file mode 100644 index 000000000..3276b2db5 --- /dev/null +++ b/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyExtensionData.cs @@ -0,0 +1,16 @@ +// 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. + +namespace ForTestingUseOnly +{ + using WixToolset.Data; + using WixToolset.Extensibility; + + public sealed class ForTestingUseOnlyExtensionData : BaseExtensionData + { + public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition) + { + symbolDefinition = ForTestingUseOnlySymbolDefinitions.ByName(name); + return symbolDefinition != null; + } + } +} diff --git a/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyExtensionFactory.cs b/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyExtensionFactory.cs new file mode 100644 index 000000000..f71a0c2ef --- /dev/null +++ b/src/test/burn/ForTestingUseOnlyExtension/ForTestingUseOnlyExtensionFactory.cs @@ -0,0 +1,18 @@ +// 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. + +namespace ForTestingUseOnly +{ + using System; + using System.Collections.Generic; + using WixToolset.Extensibility; + + public class ForTestingUseOnlyExtensionFactory : BaseExtensionFactory + { + protected override IReadOnlyCollection ExtensionTypes => new[] + { + typeof(ForTestingUseOnlyCompiler), + typeof(ForTestingUseOnlyExtensionData), + typeof(ForTestingUseOnlyBurnBackendExtension), + }; + } +} diff --git a/src/test/burn/ForTestingUseOnlyExtension/Symbols/ForTestingUseOnlyBundleSymbol.cs b/src/test/burn/ForTestingUseOnlyExtension/Symbols/ForTestingUseOnlyBundleSymbol.cs new file mode 100644 index 000000000..a17dfe316 --- /dev/null +++ b/src/test/burn/ForTestingUseOnlyExtension/Symbols/ForTestingUseOnlyBundleSymbol.cs @@ -0,0 +1,47 @@ +// 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. + +namespace ForTestingUseOnly +{ + using WixToolset.Data; + using ForTestingUseOnly.Symbols; + + public static partial class ForTestingUseOnlySymbolDefinitions + { + public static readonly IntermediateSymbolDefinition ForTestingUseOnlyBundle = new IntermediateSymbolDefinition( + ForTestingUseOnlySymbolDefinitionType.ForTestingUseOnlyBundle.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(ForTestingUseOnlyBundleSymbolFields.BundleId), IntermediateFieldType.String), + }, + typeof(ForTestingUseOnlyBundleSymbol)); + } +} + +namespace ForTestingUseOnly.Symbols +{ + using WixToolset.Data; + + public enum ForTestingUseOnlyBundleSymbolFields + { + BundleId, + } + + public class ForTestingUseOnlyBundleSymbol : IntermediateSymbol + { + public ForTestingUseOnlyBundleSymbol() : base(ForTestingUseOnlySymbolDefinitions.ForTestingUseOnlyBundle, null, null) + { + } + + public ForTestingUseOnlyBundleSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ForTestingUseOnlySymbolDefinitions.ForTestingUseOnlyBundle, sourceLineNumber, id) + { + } + + public IntermediateField this[ForTestingUseOnlyBundleSymbolFields index] => this.Fields[(int)index]; + + public string BundleId + { + get => this.Fields[(int)ForTestingUseOnlyBundleSymbolFields.BundleId].AsString(); + set => this.Set((int)ForTestingUseOnlyBundleSymbolFields.BundleId, value); + } + } +} diff --git a/src/test/burn/ForTestingUseOnlyExtension/Symbols/ForTestingUseOnlySymbolDefinitions.cs b/src/test/burn/ForTestingUseOnlyExtension/Symbols/ForTestingUseOnlySymbolDefinitions.cs new file mode 100644 index 000000000..82c3833e6 --- /dev/null +++ b/src/test/burn/ForTestingUseOnlyExtension/Symbols/ForTestingUseOnlySymbolDefinitions.cs @@ -0,0 +1,43 @@ +// 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. + +namespace ForTestingUseOnly +{ + using System; + using WixToolset.Data; + using WixToolset.Data.Burn; + + public enum ForTestingUseOnlySymbolDefinitionType + { + ForTestingUseOnlyBundle, + } + + public static partial class ForTestingUseOnlySymbolDefinitions + { + public static IntermediateSymbolDefinition ByName(string name) + { + if (!Enum.TryParse(name, out ForTestingUseOnlySymbolDefinitionType type)) + { + return null; + } + + return ByType(type); + } + + public static IntermediateSymbolDefinition ByType(ForTestingUseOnlySymbolDefinitionType type) + { + switch (type) + { + case ForTestingUseOnlySymbolDefinitionType.ForTestingUseOnlyBundle: + return ForTestingUseOnlySymbolDefinitions.ForTestingUseOnlyBundle; + + default: + throw new ArgumentOutOfRangeException(nameof(type)); + } + } + + static ForTestingUseOnlySymbolDefinitions() + { + ForTestingUseOnlyBundle.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag); + } + } +} diff --git a/src/test/burn/TestData/DependencyTests/BundleF/BundleF.props b/src/test/burn/TestData/DependencyTests/BundleF/BundleF.props new file mode 100644 index 000000000..91fdc82c3 --- /dev/null +++ b/src/test/burn/TestData/DependencyTests/BundleF/BundleF.props @@ -0,0 +1,10 @@ + + + + Bundle + {EC2B2B3F-E57C-45A4-A0E8-762156DAD99D} + + + + + diff --git a/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wixproj b/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wixproj index 4473657a3..754819404 100644 --- a/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wixproj +++ b/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wixproj @@ -1,13 +1,10 @@ + Bundle - {EC2B2B3F-E57C-45A4-A0E8-762156DAD99D} 1.0.0.0 - - - @@ -18,4 +15,7 @@ + + + \ No newline at end of file diff --git a/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wxs b/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wxs index 1347836a0..0f51b00db 100644 --- a/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wxs +++ b/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wxs @@ -1,7 +1,8 @@  - + + diff --git a/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOnA.wixproj b/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOnA.wixproj index 2674b9d65..14072fedb 100644 --- a/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOnA.wixproj +++ b/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOnA.wixproj @@ -17,4 +17,7 @@ + + + \ No newline at end of file diff --git a/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOn.wxs b/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOnA.wxs similarity index 86% rename from src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOn.wxs rename to src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOnA.wxs index 30fba6570..c1b656560 100644 --- a/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOn.wxs +++ b/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOnA.wxs @@ -2,8 +2,9 @@ - + + diff --git a/src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wixproj b/src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wixproj index 542f3562b..c467222f8 100644 --- a/src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wixproj +++ b/src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wixproj @@ -6,7 +6,6 @@ 1.0.0.0 - @@ -18,4 +17,7 @@ + + + \ No newline at end of file diff --git a/src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wxs b/src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wxs new file mode 100644 index 000000000..8a5722f7a --- /dev/null +++ b/src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wxs @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/test/burn/TestData/DependencyTests/BundleFv2/BundleFv2.wixproj b/src/test/burn/TestData/DependencyTests/BundleFv2/BundleFv2.wixproj new file mode 100644 index 000000000..7b6aa9f30 --- /dev/null +++ b/src/test/burn/TestData/DependencyTests/BundleFv2/BundleFv2.wixproj @@ -0,0 +1,17 @@ + + + + + 2.0.0.0 + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/burn/TestData/DependencyTests/BundleFv2/BundleFv2.wxs b/src/test/burn/TestData/DependencyTests/BundleFv2/BundleFv2.wxs new file mode 100644 index 000000000..1347836a0 --- /dev/null +++ b/src/test/burn/TestData/DependencyTests/BundleFv2/BundleFv2.wxs @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/test/burn/WixToolsetTest.BurnE2E/BurnE2ETests.cs b/src/test/burn/WixToolsetTest.BurnE2E/BurnE2ETests.cs index 392b675d9..a7402d94e 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/BurnE2ETests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/BurnE2ETests.cs @@ -15,6 +15,13 @@ public abstract class BurnE2ETests : WixTestBase, IDisposable private Stack Installers { get; } = new Stack(); + protected bool SupportAddonAndPatchRelatedBundles => +#if SUPPORT_ADDON_AND_PATCH_RELATED_BUNDLES + true; +#else + false; +#endif + protected BundleInstaller CreateBundleInstaller(string name) { var installer = new BundleInstaller(this.TestContext, name); diff --git a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs index 309241d98..b08cd54fb 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs @@ -123,11 +123,7 @@ public void CanKeepUpgradedPackageAfterUninstallUpgradedBundle() bundleAv1.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.1.0"); } -#if SUPPORT_ADDON_AND_PATCH_RELATED_BUNDLES [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6401")] -#else - [Fact(Skip = "addon/patch related bundle")] -#endif public void CanMinorUpgradeDependencyPackageFromPatchBundle() { var originalVersion = "1.0.0.0"; @@ -145,34 +141,39 @@ public void CanMinorUpgradeDependencyPackageFromPatchBundle() packageBv101.VerifyInstalled(false); bundleJ.Install(); - bundleJ.VerifyRegisteredAndInPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleJ.VerifyRegisteredAndInPackageCache(); - packageA.VerifyInstalled(true); - packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion); - packageBv1.VerifyInstalled(true); + packageA.VerifyInstalled(true); + packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion); + packageBv1.VerifyInstalled(true); + } bundleJ_Patch.Install(); - bundleJ_Patch.VerifyRegisteredAndInPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleJ_Patch.VerifyRegisteredAndInPackageCache(); - packageA.VerifyInstalled(true); - packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion); - packageBv1.VerifyInstalled(false); - packageBv101.VerifyInstalled(true); + packageA.VerifyInstalled(true); + packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion); + packageBv1.VerifyInstalled(false); + packageBv101.VerifyInstalled(true); + } bundleJ.Uninstall(); - bundleJ.VerifyUnregisteredAndRemovedFromPackageCache(); - bundleJ_Patch.VerifyUnregisteredAndRemovedFromPackageCache(); - - packageA.VerifyInstalled(false); - packageBv1.VerifyInstalled(false); - packageBv101.VerifyInstalled(false); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleJ.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleJ_Patch.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageA.VerifyInstalled(false); + packageBv1.VerifyInstalled(false); + packageBv101.VerifyInstalled(false); + } } -#if SUPPORT_ADDON_AND_PATCH_RELATED_BUNDLES [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6401")] -#else - [Fact(Skip = "addon/patch related bundle")] -#endif public void CanMinorUpgradeDependencyPackageFromPatchBundleThenUninstallToRestoreBase() { var originalVersion = "1.0.0.0"; @@ -190,41 +191,49 @@ public void CanMinorUpgradeDependencyPackageFromPatchBundleThenUninstallToRestor packageBv101.VerifyInstalled(false); bundleJ.Install(); - bundleJ.VerifyRegisteredAndInPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleJ.VerifyRegisteredAndInPackageCache(); - packageA.VerifyInstalled(true); - packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion); - packageBv1.VerifyInstalled(true); + packageA.VerifyInstalled(true); + packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion); + packageBv1.VerifyInstalled(true); + } bundleJ_Patch.Install(); - bundleJ_Patch.VerifyRegisteredAndInPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleJ_Patch.VerifyRegisteredAndInPackageCache(); - packageA.VerifyInstalled(true); - packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion); - packageBv1.VerifyInstalled(false); - packageBv101.VerifyInstalled(true); + packageA.VerifyInstalled(true); + packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion); + packageBv1.VerifyInstalled(false); + packageBv101.VerifyInstalled(true); + } bundleJ_Patch.Uninstall(); - bundleJ_Patch.VerifyUnregisteredAndRemovedFromPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleJ_Patch.VerifyUnregisteredAndRemovedFromPackageCache(); - packageA.VerifyInstalled(true); - packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion); - packageBv1.VerifyInstalled(true); - packageBv101.VerifyInstalled(false); + packageA.VerifyInstalled(true); + packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion); + packageBv1.VerifyInstalled(true); + packageBv101.VerifyInstalled(false); + } bundleJ.Uninstall(); - bundleJ.VerifyUnregisteredAndRemovedFromPackageCache(); - - packageA.VerifyInstalled(false); - packageBv1.VerifyInstalled(false); - packageBv101.VerifyInstalled(false); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleJ.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageA.VerifyInstalled(false); + packageBv1.VerifyInstalled(false); + packageBv101.VerifyInstalled(false); + } } -#if SUPPORT_ADDON_AND_PATCH_RELATED_BUNDLES [Fact] -#else - [Fact(Skip = "addon/patch related bundle")] -#endif public void CanUninstallBaseWithAddOnsWhenAllSharePackages() { var testRegistryValueExe = "ExeA"; @@ -239,33 +248,103 @@ public void CanUninstallBaseWithAddOnsWhenAllSharePackages() packageB.VerifyInstalled(false); bundleF.Install(); - bundleF.VerifyRegisteredAndInPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleF.VerifyRegisteredAndInPackageCache(); - packageA.VerifyInstalled(true); - packageB.VerifyInstalled(true); + packageA.VerifyInstalled(true); + packageB.VerifyInstalled(true); + } bundleF_AddOnA.Install(); - bundleF_AddOnA.VerifyRegisteredAndInPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleF_AddOnA.VerifyRegisteredAndInPackageCache(); - packageA.VerifyInstalled(true); - bundleF.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0"); - packageB.VerifyInstalled(true); + packageA.VerifyInstalled(true); + bundleF.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0"); + packageB.VerifyInstalled(true); + } bundleF_AddOnB.Install(); - bundleF_AddOnB.VerifyRegisteredAndInPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleF_AddOnB.VerifyRegisteredAndInPackageCache(); - packageA.VerifyInstalled(true); - bundleF.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0"); - packageB.VerifyInstalled(true); + packageA.VerifyInstalled(true); + bundleF.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0"); + packageB.VerifyInstalled(true); + } bundleF.Uninstall(); - bundleF.VerifyUnregisteredAndRemovedFromPackageCache(); - bundleF_AddOnA.VerifyUnregisteredAndRemovedFromPackageCache(); - bundleF_AddOnB.VerifyUnregisteredAndRemovedFromPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleF.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleF_AddOnA.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleF_AddOnB.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageA.VerifyInstalled(false); + bundleF.VerifyExeTestRegistryRootDeleted(testRegistryValueExe); + packageB.VerifyInstalled(false); + } + } + + [Fact] + public void CanUpgradeBaseWithAddOns() + { + var testRegistryValueExe = "ExeA"; + + var packageA = this.CreatePackageInstaller("PackageAv1"); + var packageB = this.CreatePackageInstaller("PackageB"); + var bundleF = this.CreateBundleInstaller("BundleF"); + var bundleF_AddOnA = this.CreateBundleInstaller("BundleF_AddOnA"); + var bundleF_AddOnB = this.CreateBundleInstaller("BundleF_AddOnB"); + var bundleFv2 = this.CreateBundleInstaller("BundleFv2"); packageA.VerifyInstalled(false); - bundleF.VerifyExeTestRegistryRootDeleted(testRegistryValueExe); packageB.VerifyInstalled(false); + + bundleF.Install(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleF.VerifyRegisteredAndInPackageCache(); + + packageA.VerifyInstalled(true); + packageB.VerifyInstalled(true); + } + + bundleF_AddOnA.Install(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleF_AddOnA.VerifyRegisteredAndInPackageCache(); + + packageA.VerifyInstalled(true); + bundleF.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0"); + packageB.VerifyInstalled(true); + } + + bundleF_AddOnB.Install(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleF_AddOnB.VerifyRegisteredAndInPackageCache(); + + packageA.VerifyInstalled(true); + bundleF.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0"); + packageB.VerifyInstalled(true); + } + + bundleFv2.Install(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleFv2.VerifyRegisteredAndInPackageCache(); + bundleF.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleF_AddOnA.VerifyRegisteredAndInPackageCache(); + bundleF_AddOnB.VerifyRegisteredAndInPackageCache(); + + packageA.VerifyInstalled(true); + bundleF.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0"); + packageB.VerifyInstalled(true); + } } [Fact] @@ -343,11 +422,7 @@ public void CanUninstallDependencyPackagesWithBundlesUninstalledInReverseOrder() packageB.VerifyInstalled(false); } -#if SUPPORT_ADDON_AND_PATCH_RELATED_BUNDLES [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6401")] -#else - [Fact(Skip = "addon/patch related bundle")] -#endif public void CanUpgradePatchBundleWithAdditionalPatch() { var originalVersion = "1.0.0.0"; @@ -365,33 +440,45 @@ public void CanUpgradePatchBundleWithAdditionalPatch() packageB.VerifyInstalled(false); bundleF.Install(); - bundleF.VerifyRegisteredAndInPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleF.VerifyRegisteredAndInPackageCache(); - packageA.VerifyInstalled(true); - packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion); - packageB.VerifyInstalled(true); + packageA.VerifyInstalled(true); + packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion); + packageB.VerifyInstalled(true); + } bundleF_PatchAv101.Install(); - bundleF_PatchAv101.VerifyRegisteredAndInPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleF_PatchAv101.VerifyRegisteredAndInPackageCache(); - packageA.VerifyInstalled(true); - packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion); - packageB.VerifyInstalled(false); + packageA.VerifyInstalled(true); + packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion); + packageB.VerifyInstalled(false); + } bundleF_PatchAv102.Install(); - bundleF_PatchAv102.VerifyRegisteredAndInPackageCache(); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleF_PatchAv102.VerifyRegisteredAndInPackageCache(); - packageA.VerifyInstalled(true); - packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion2); - packageB.VerifyInstalled(false); + packageA.VerifyInstalled(true); + packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion2); + packageB.VerifyInstalled(false); + } bundleF.Uninstall(); - bundleF.VerifyUnregisteredAndRemovedFromPackageCache(); - bundleF_PatchAv101.VerifyUnregisteredAndRemovedFromPackageCache(); - bundleF_PatchAv102.VerifyUnregisteredAndRemovedFromPackageCache(); - - packageA.VerifyInstalled(false); - packageB.VerifyInstalled(false); + if (this.SupportAddonAndPatchRelatedBundles) + { + bundleF.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleF_PatchAv101.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleF_PatchAv102.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageA.VerifyInstalled(false); + packageB.VerifyInstalled(false); + } } [Fact]