From 9286dc177012bc8741fb1c206e00d0fbcd02f598 Mon Sep 17 00:00:00 2001 From: Bob Arnson Date: Thu, 20 Mar 2025 21:14:12 -0400 Subject: E2E test to validate update registration. --- .../BundleAv1/Bundle.wxs | 58 ++++++++++++++++++++++ .../BundleAv1/BundleA.props | 7 +++ .../BundleAv1/BundleAv1.wixproj | 12 +++++ .../BundleAv1/BundleAv1.wxs | 10 ++++ .../BundleAv2/BundleAv2.wixproj | 18 +++++++ .../BundleAv2/BundleAv2.wxs | 10 ++++ .../PackageAv1/PackageA.props | 9 ++++ .../PackageAv1/PackageAv1.wixproj | 4 ++ .../PackageAv2/PackageAv2.wixproj | 7 +++ .../burn/WixTestTools/BundleUpdateRegistration.cs | 57 +++++++++++++++++++++ src/test/burn/WixTestTools/BundleVerifier.cs | 37 ++++++++++++++ .../OptionalUpdateRegistrationTests.cs | 41 +++++++++++++++ 12 files changed, 270 insertions(+) create mode 100644 src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/Bundle.wxs create mode 100644 src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleA.props create mode 100644 src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wixproj create mode 100644 src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wxs create mode 100644 src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wixproj create mode 100644 src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wxs create mode 100644 src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageA.props create mode 100644 src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageAv1.wixproj create mode 100644 src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv2/PackageAv2.wixproj create mode 100644 src/test/burn/WixTestTools/BundleUpdateRegistration.cs create mode 100644 src/test/burn/WixToolsetTest.BurnE2E/OptionalUpdateRegistrationTests.cs diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/Bundle.wxs b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/Bundle.wxs new file mode 100644 index 00000000..0d9f786a --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/Bundle.wxs @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleA.props b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleA.props new file mode 100644 index 00000000..1887f94e --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleA.props @@ -0,0 +1,7 @@ + + + + Bundle + {9510DDE7-CD4F-45B3-9D57-3F7EA04DB33D} + + diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wixproj b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wixproj new file mode 100644 index 00000000..0dea1e40 --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wixproj @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wxs b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wxs new file mode 100644 index 00000000..7bf16212 --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wxs @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wixproj b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wixproj new file mode 100644 index 00000000..271bf54b --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wixproj @@ -0,0 +1,18 @@ + + + + + 2.0.0.0 + + + + + + + + + + + + + diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wxs b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wxs new file mode 100644 index 00000000..5cbee5a8 --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wxs @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageA.props b/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageA.props new file mode 100644 index 00000000..25ae3f42 --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageA.props @@ -0,0 +1,9 @@ + + + + {30746E93-9A4A-48EC-BAEA-3093A2530E73} + + + + + \ No newline at end of file diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageAv1.wixproj b/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageAv1.wixproj new file mode 100644 index 00000000..45d3b2c8 --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageAv1.wixproj @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv2/PackageAv2.wixproj b/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv2/PackageAv2.wixproj new file mode 100644 index 00000000..d4455f2b --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv2/PackageAv2.wixproj @@ -0,0 +1,7 @@ + + + + + 2.0.0.0 + + diff --git a/src/test/burn/WixTestTools/BundleUpdateRegistration.cs b/src/test/burn/WixTestTools/BundleUpdateRegistration.cs new file mode 100644 index 00000000..2ce68122 --- /dev/null +++ b/src/test/burn/WixTestTools/BundleUpdateRegistration.cs @@ -0,0 +1,57 @@ +// 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 WixTestTools +{ + using System; + using Microsoft.Win32; + + public class BundleUpdateRegistration + { + public const string BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PACKAGE_NAME = "PackageName"; + public const string BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PACKAGE_VERSION = "PackageVersion"; + public const string BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PUBLISHER = "Publisher"; + public const string BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PUBLISHING_GROUP = "PublishingGroup"; + + public string PackageName { get; set; } + + public string PackageVersion { get; set; } + + public string Publisher { get; set; } + + public string PublishingGroup { get; set; } + + public static bool TryGetPerMachineBundleUpdateRegistration(string manufacturer, string productFamily, string name, bool x64, out BundleUpdateRegistration registration) + { + return TryGetUpdateRegistration(manufacturer, productFamily, name, x64, perUser: false, out registration); + } + + public static bool TryGetPerUserBundleUpdateRegistration(string manufacturer, string productFamily, string name, out BundleUpdateRegistration registration) + { + return TryGetUpdateRegistration(manufacturer, productFamily, name, x64: true, perUser: true, out registration); + } + + private static bool TryGetUpdateRegistration(string manufacturer, string productFamily, string name, bool x64, bool perUser, out BundleUpdateRegistration registration) + { + var baseKey = perUser ? Registry.CurrentUser : Registry.LocalMachine; + var baseKeyPath = x64 ? @$"SOFTWARE\{manufacturer}\Updates\{productFamily}\{name}" + : @$"SOFTWARE\WOW6432Node\{manufacturer}\Updates\{productFamily}\{name}"; + using var idKey = baseKey.OpenSubKey(baseKeyPath); + + if (idKey == null) + { + registration = null; + return false; + } + + registration = new BundleUpdateRegistration() + { + PackageName = idKey.GetValue(BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PACKAGE_NAME) as string, + PackageVersion = idKey.GetValue(BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PACKAGE_VERSION) as string, + Publisher = idKey.GetValue(BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PUBLISHER) as string, + PublishingGroup = idKey.GetValue(BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PUBLISHING_GROUP) as string, + }; + + return true; + } + } +} diff --git a/src/test/burn/WixTestTools/BundleVerifier.cs b/src/test/burn/WixTestTools/BundleVerifier.cs index da61d96e..b6181047 100644 --- a/src/test/burn/WixTestTools/BundleVerifier.cs +++ b/src/test/burn/WixTestTools/BundleVerifier.cs @@ -6,6 +6,7 @@ namespace WixTestTools using System.IO; using System.Linq; using System.Text; + using System.Xml.Linq; using Microsoft.Win32; using WixInternal.TestSupport; using WixToolset.Data; @@ -23,6 +24,8 @@ namespace WixTestTools private WixBundleSymbol BundleSymbol { get; set; } + private WixUpdateRegistrationSymbol UpdateRegistrationSymbol { get; set; } + private WixBundleSymbol GetBundleSymbol() { if (this.BundleSymbol == null) @@ -36,6 +39,19 @@ namespace WixTestTools return this.BundleSymbol; } + private WixUpdateRegistrationSymbol GetUpdateRegistrationSymbol() + { + if (this.UpdateRegistrationSymbol == null) + { + using var wixOutput = WixOutput.Read(this.BundlePdb); + var intermediate = Intermediate.Load(wixOutput); + var section = intermediate.Sections.Single(); + this.UpdateRegistrationSymbol = section.Symbols.OfType().Single(); + } + + return this.UpdateRegistrationSymbol; + } + public string GetFullBurnPolicyRegistryPath() { var bundleSymbol = this.GetBundleSymbol(); @@ -118,6 +134,27 @@ namespace WixTestTools } } + public bool TryGetUpdateRegistration(out BundleUpdateRegistration registration) + { + var bundleSymbol = this.GetBundleSymbol(); + var x64 = bundleSymbol.Platform != Platform.X86; + + var updateRegistrationSymbol = this.GetUpdateRegistrationSymbol(); + var manufacturer = updateRegistrationSymbol.Manufacturer; + var productFamily = updateRegistrationSymbol.ProductFamily; + var name = updateRegistrationSymbol.Name; + + + if (bundleSymbol.PerMachine) + { + return BundleUpdateRegistration.TryGetPerMachineBundleUpdateRegistration(manufacturer, productFamily, name, x64, out registration); + } + else + { + return BundleUpdateRegistration.TryGetPerUserBundleUpdateRegistration(manufacturer, productFamily, name, out registration); + } + } + public BundleRegistration VerifyRegisteredAndInPackageCache(int? expectedSystemComponent = null) { Assert.True(this.TryGetRegistration(out var registration)); diff --git a/src/test/burn/WixToolsetTest.BurnE2E/OptionalUpdateRegistrationTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/OptionalUpdateRegistrationTests.cs new file mode 100644 index 00000000..632d18ec --- /dev/null +++ b/src/test/burn/WixToolsetTest.BurnE2E/OptionalUpdateRegistrationTests.cs @@ -0,0 +1,41 @@ +// 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 WixToolsetTest.BurnE2E +{ + using System; + using System.IO; + using WixTestTools; + using Xunit; + using Xunit.Abstractions; + + public class OptionalUpdateRegistrationTests : BurnE2ETests + { + public OptionalUpdateRegistrationTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } + + [RuntimeFact] + public void BundleUpdateRegistrationIsStickyAndAccurateAcrossUpgrades() + { + var packageAv1 = this.CreatePackageInstaller("PackageAv1"); + var packageAv2 = this.CreatePackageInstaller("PackageAv2"); + var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); + var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); + + bundleAv1.Install(); + bundleAv1.VerifyRegisteredAndInPackageCache(); + bundleAv1.TryGetUpdateRegistration(out var v1Registration); + + bundleAv2.Install(); + bundleAv2.VerifyRegisteredAndInPackageCache(); + bundleAv1.TryGetUpdateRegistration(out var v2Registration); + + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + + Assert.NotNull(v1Registration); + Assert.NotNull(v2Registration); + Assert.Equal(v1Registration?.Publisher, v2Registration?.Publisher); + Assert.Equal(v1Registration?.PublishingGroup, v2Registration?.PublishingGroup); + Assert.Equal(v1Registration?.PackageName, v2Registration?.PackageName); + Assert.NotEqual(v1Registration?.PackageVersion, v2Registration?.PackageVersion); + } + } +} -- cgit v1.2.3-55-g6feb