From 81908a5ec1647d76b45f50e4a18c37e1544818be Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Thu, 11 Mar 2021 17:54:30 -0600 Subject: Port forward compatible tests from old repo. --- .../BundleAv1/Bundle.wxs | 40 ++ .../BundleAv1/BundleA.props | 7 + .../BundleAv1/BundleAv1.wixproj | 12 + .../BundleAv1/BundleAv1.wxs | 10 + .../BundleAv2/BundleAv2.wixproj | 18 + .../BundleAv2/BundleAv2.wxs | 10 + .../BundleCv1/Bundle.wxs | 40 ++ .../BundleCv1/BundleC.props | 7 + .../BundleCv1/BundleCv1.wixproj | 12 + .../BundleCv1/BundleCv1.wxs | 10 + .../BundleCv2/BundleCv2.wixproj | 18 + .../BundleCv2/BundleCv2.wxs | 10 + .../PackageAv1/PackageA.props | 9 + .../PackageAv1/PackageAv1.wixproj | 4 + .../PackageAv2/PackageAv2.wixproj | 7 + .../PackageCv1/PackageC.props | 9 + .../PackageCv1/PackageCv1.wixproj | 4 + .../PackageCv2/PackageCv2.wixproj | 7 + src/TestData/Templates/PackagePerUser.wxs | 65 +++ src/WixTestTools/BundleRegistration.cs | 26 ++ .../ForwardCompatibleBundleTests.cs | 469 +++++++++++++++++++++ 21 files changed, 794 insertions(+) create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleAv1/Bundle.wxs create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleA.props create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wixproj create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wxs create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wixproj create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wxs create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleCv1/Bundle.wxs create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleC.props create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wixproj create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wxs create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wixproj create mode 100644 src/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wxs create mode 100644 src/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageA.props create mode 100644 src/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageAv1.wixproj create mode 100644 src/TestData/ForwardCompatibleBundleTests/PackageAv2/PackageAv2.wixproj create mode 100644 src/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageC.props create mode 100644 src/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageCv1.wixproj create mode 100644 src/TestData/ForwardCompatibleBundleTests/PackageCv2/PackageCv2.wixproj create mode 100644 src/TestData/Templates/PackagePerUser.wxs create mode 100644 src/WixToolsetTest.BurnE2E/ForwardCompatibleBundleTests.cs diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleAv1/Bundle.wxs b/src/TestData/ForwardCompatibleBundleTests/BundleAv1/Bundle.wxs new file mode 100644 index 00000000..175d9a1f --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleAv1/Bundle.wxs @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleA.props b/src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleA.props new file mode 100644 index 00000000..329ea107 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleA.props @@ -0,0 +1,7 @@ + + + + Bundle + {5ACFAE02-DDF0-4F1C-BEAD-1E0998E5CF9B} + + diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wixproj b/src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wixproj new file mode 100644 index 00000000..dea8b4f4 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wixproj @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wxs b/src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wxs new file mode 100644 index 00000000..7bf16212 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wxs @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wixproj b/src/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wixproj new file mode 100644 index 00000000..dec1d299 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wixproj @@ -0,0 +1,18 @@ + + + + + 2.0.0.0 + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wxs b/src/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wxs new file mode 100644 index 00000000..5cbee5a8 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wxs @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleCv1/Bundle.wxs b/src/TestData/ForwardCompatibleBundleTests/BundleCv1/Bundle.wxs new file mode 100644 index 00000000..dd305e42 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleCv1/Bundle.wxs @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleC.props b/src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleC.props new file mode 100644 index 00000000..73a9bb63 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleC.props @@ -0,0 +1,7 @@ + + + + Bundle + {D387D602-533C-495D-B14E-AA9D46AF314B} + + diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wixproj b/src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wixproj new file mode 100644 index 00000000..28c6a478 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wixproj @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wxs b/src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wxs new file mode 100644 index 00000000..43e75910 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wxs @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wixproj b/src/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wixproj new file mode 100644 index 00000000..51f61d73 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wixproj @@ -0,0 +1,18 @@ + + + + + 2.0.0.0 + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wxs b/src/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wxs new file mode 100644 index 00000000..53115c96 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wxs @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageA.props b/src/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageA.props new file mode 100644 index 00000000..de83c1f5 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageA.props @@ -0,0 +1,9 @@ + + + + {F764127F-8893-4483-A136-F53660C32423} + + + + + \ No newline at end of file diff --git a/src/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageAv1.wixproj b/src/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageAv1.wixproj new file mode 100644 index 00000000..45d3b2c8 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageAv1.wixproj @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/TestData/ForwardCompatibleBundleTests/PackageAv2/PackageAv2.wixproj b/src/TestData/ForwardCompatibleBundleTests/PackageAv2/PackageAv2.wixproj new file mode 100644 index 00000000..b419f663 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/PackageAv2/PackageAv2.wixproj @@ -0,0 +1,7 @@ + + + + + 2.0.0.0 + + \ No newline at end of file diff --git a/src/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageC.props b/src/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageC.props new file mode 100644 index 00000000..91d3bdda --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageC.props @@ -0,0 +1,9 @@ + + + + {DF1C1C42-F5B9-4167-914B-1AF97E829C48} + + + + + \ No newline at end of file diff --git a/src/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageCv1.wixproj b/src/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageCv1.wixproj new file mode 100644 index 00000000..45615706 --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageCv1.wixproj @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/TestData/ForwardCompatibleBundleTests/PackageCv2/PackageCv2.wixproj b/src/TestData/ForwardCompatibleBundleTests/PackageCv2/PackageCv2.wixproj new file mode 100644 index 00000000..640ad21d --- /dev/null +++ b/src/TestData/ForwardCompatibleBundleTests/PackageCv2/PackageCv2.wixproj @@ -0,0 +1,7 @@ + + + + + 2.0.0.0 + + \ No newline at end of file diff --git a/src/TestData/Templates/PackagePerUser.wxs b/src/TestData/Templates/PackagePerUser.wxs new file mode 100644 index 00000000..e985966c --- /dev/null +++ b/src/TestData/Templates/PackagePerUser.wxs @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/WixTestTools/BundleRegistration.cs b/src/WixTestTools/BundleRegistration.cs index 1a066232..bf9e2903 100644 --- a/src/WixTestTools/BundleRegistration.cs +++ b/src/WixTestTools/BundleRegistration.cs @@ -151,5 +151,31 @@ namespace WixTestTools return registration; } + + public static bool TryGetDependencyProviderValue(string providerId, string name, out string value) + { + value = null; + + string key = String.Format(@"Installer\Dependencies\{0}", providerId); + using (RegistryKey providerKey = Registry.ClassesRoot.OpenSubKey(key)) + { + if (null == providerKey) + { + return false; + } + + value = providerKey.GetValue(name) as string; + return value != null; + } + } + + public static bool DependencyDependentExists(string providerId, string dependentId) + { + string key = String.Format(@"Installer\Dependencies\{0}\Dependents\{1}", providerId, dependentId); + using (RegistryKey dependentKey = Registry.ClassesRoot.OpenSubKey(key)) + { + return null != dependentKey; + } + } } } diff --git a/src/WixToolsetTest.BurnE2E/ForwardCompatibleBundleTests.cs b/src/WixToolsetTest.BurnE2E/ForwardCompatibleBundleTests.cs new file mode 100644 index 00000000..eb649c86 --- /dev/null +++ b/src/WixToolsetTest.BurnE2E/ForwardCompatibleBundleTests.cs @@ -0,0 +1,469 @@ +// 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 ForwardCompatibleBundleTests : BurnE2ETests + { + public ForwardCompatibleBundleTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } + + private const string BundleAProviderId = "~" + nameof(ForwardCompatibleBundleTests) + "_BundleA"; + private const string BundleCProviderId = "~" + nameof(ForwardCompatibleBundleTests) + "_BundleC"; + private const string V100 = "1.0.0.0"; + private const string V200 = "2.0.0.0"; + + [Fact] + public void CanTrack1ForwardCompatibleDependentThroughMajorUpgrade() + { + string providerId = BundleAProviderId; + string parent = "~BundleAv1"; + string parentSwitch = String.Concat("-parent ", parent); + + var packageAv1 = this.CreatePackageInstaller("PackageAv1"); + var packageAv2 = this.CreatePackageInstaller("PackageAv2"); + var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); + var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + + // Install the v1 bundle with a parent. + bundleAv1.Install(arguments: parentSwitch); + bundleAv1.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(true); + packageAv2.VerifyInstalled(false); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion)); + Assert.Equal(V100, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + + // Upgrade with the v2 bundle. + bundleAv2.Install(); + bundleAv2.VerifyRegisteredAndInPackageCache(); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + + // Uninstall the v2 bundle and nothing should happen because there is still a parent. + bundleAv2.Uninstall(); + bundleAv2.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + + // Uninstall the v1 bundle with passthrough and all should be removed. + bundleAv1.Uninstall(arguments: parentSwitch); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + } + + [Fact] + public void CanTrack1ForwardCompatibleDependentThroughMajorUpgradeWithParentNone() + { + string providerId = BundleAProviderId; + string parent = "~BundleAv1"; + string parentSwitch = String.Concat("-parent ", parent); + + var packageAv1 = this.CreatePackageInstaller("PackageAv1"); + var packageAv2 = this.CreatePackageInstaller("PackageAv2"); + var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); + var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + + // Install the v1 bundle with a parent. + bundleAv1.Install(arguments: parentSwitch); + bundleAv1.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(true); + packageAv2.VerifyInstalled(false); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion)); + Assert.Equal(V100, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + + // Upgrade with the v2 bundle but prevent self parent being registered. + bundleAv2.Install(arguments: "-parent:none"); + bundleAv2.VerifyRegisteredAndInPackageCache(); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + + // Uninstall the v1 bundle with passthrough and all should be removed. + bundleAv1.Uninstall(arguments: parentSwitch); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + } + + [Fact] + public void CanTrack2ForwardCompatibleDependentsThroughMajorUpgrade() + { + string providerId = BundleAProviderId; + string parent = "~BundleAv1"; + string parent2 = "~BundleAv1_Parent2"; + string parentSwitch = String.Concat("-parent ", parent); + string parent2Switch = String.Concat("-parent ", parent2); + + var packageAv1 = this.CreatePackageInstaller("PackageAv1"); + var packageAv2 = this.CreatePackageInstaller("PackageAv2"); + var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); + var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + + // Install the v1 bundle with a parent. + bundleAv1.Install(arguments: parentSwitch); + bundleAv1.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(true); + packageAv2.VerifyInstalled(false); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion)); + Assert.Equal(V100, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + + // Install the v1 bundle with a second parent. + bundleAv1.Install(arguments: parent2Switch); + bundleAv1.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(true); + packageAv2.VerifyInstalled(false); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V100, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + + // Upgrade with the v2 bundle. + bundleAv2.Install(); + bundleAv2.VerifyRegisteredAndInPackageCache(); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + + // Uninstall the v2 bundle and nothing should happen because there is still a parent. + bundleAv2.Uninstall(); + bundleAv2.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + + // Uninstall one parent of the v1 bundle and nothing should happen because there is still a parent. + bundleAv1.Uninstall(arguments: parentSwitch); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleAv2.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.False(BundleRegistration.DependencyDependentExists(providerId, parent)); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + + // Uninstall the v1 bundle with passthrough with second parent and all should be removed. + bundleAv1.Uninstall(arguments: parent2Switch); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + } + + [Fact] + public void CanTrack2ForwardCompatibleDependentsThroughMajorUpgradePerUser() + { + string providerId = BundleCProviderId; + string parent = "~BundleCv1"; + string parent2 = "~BundleCv1_Parent2"; + string parentSwitch = String.Concat("-parent ", parent); + string parent2Switch = String.Concat("-parent ", parent2); + + var packageCv1 = this.CreatePackageInstaller("PackageCv1"); + var packageCv2 = this.CreatePackageInstaller("PackageCv2"); + var bundleCv1 = this.CreateBundleInstaller("BundleCv1"); + var bundleCv2 = this.CreateBundleInstaller("BundleCv2"); + + packageCv1.VerifyInstalled(false); + packageCv2.VerifyInstalled(false); + + // Install the v1 bundle with a parent. + bundleCv1.Install(arguments: parentSwitch); + bundleCv1.VerifyRegisteredAndInPackageCache(); + + packageCv1.VerifyInstalled(true); + packageCv2.VerifyInstalled(false); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion)); + Assert.Equal(V100, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + + // Install the v1 bundle with a second parent. + bundleCv1.Install(arguments: parent2Switch); + bundleCv1.VerifyRegisteredAndInPackageCache(); + + packageCv1.VerifyInstalled(true); + packageCv2.VerifyInstalled(false); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V100, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + + // Upgrade with the v2 bundle. + bundleCv2.Install(); + bundleCv2.VerifyRegisteredAndInPackageCache(); + bundleCv1.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageCv1.VerifyInstalled(false); + packageCv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + + // Uninstall the v2 bundle and nothing should happen because there is still a parent. + bundleCv2.Uninstall(); + bundleCv2.VerifyRegisteredAndInPackageCache(); + + packageCv1.VerifyInstalled(false); + packageCv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + + // Uninstall one parent of the v1 bundle and nothing should happen because there is still a parent. + bundleCv1.Uninstall(arguments: parentSwitch); + bundleCv1.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleCv2.VerifyRegisteredAndInPackageCache(); + + packageCv1.VerifyInstalled(false); + packageCv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.False(BundleRegistration.DependencyDependentExists(providerId, parent)); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + + // Uninstall the v1 bundle with passthrough with second parent and all should be removed. + bundleCv1.Uninstall(arguments: parent2Switch); + bundleCv1.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleCv2.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageCv1.VerifyInstalled(false); + packageCv2.VerifyInstalled(false); + Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + } + + [Fact] + public void CanTrack2ForwardCompatibleDependentsThroughMajorUpgradeWithParent() + { + string providerId = BundleAProviderId; + string parent = "~BundleAv1"; + string parent2 = "~BundleAv1_Parent2"; + string parent3 = "~BundleAv1_Parent3"; + string parentSwitch = String.Concat("-parent ", parent); + string parent2Switch = String.Concat("-parent ", parent2); + string parent3Switch = String.Concat("-parent ", parent3); + + var packageAv1 = this.CreatePackageInstaller("PackageAv1"); + var packageAv2 = this.CreatePackageInstaller("PackageAv2"); + var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); + var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + + // Install the v1 bundle with a parent. + bundleAv1.Install(arguments: parentSwitch); + bundleAv1.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(true); + packageAv2.VerifyInstalled(false); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion)); + Assert.Equal(V100, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + + // Install the v1 bundle with a second parent. + bundleAv1.Install(arguments: parent2Switch); + bundleAv1.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(true); + packageAv2.VerifyInstalled(false); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V100, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + + // Upgrade with the v2 bundle. + bundleAv2.Install(arguments: parent3Switch); + bundleAv2.VerifyRegisteredAndInPackageCache(); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent3)); + + // Uninstall the v2 bundle and nothing should happen because there is still a parent. + bundleAv2.Uninstall(arguments: parent3Switch); + bundleAv2.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + Assert.False(BundleRegistration.DependencyDependentExists(providerId, parent3)); + + // Uninstall one parent of the v1 bundle and nothing should happen because there is still a parent. + bundleAv1.Uninstall(arguments: parentSwitch); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleAv2.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + Assert.False(BundleRegistration.DependencyDependentExists(providerId, parent)); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2)); + + // Uninstall the v1 bundle with passthrough with second parent and all should be removed. + bundleAv1.Uninstall(arguments: parent2Switch); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + } + + [Fact] + public void CanUninstallForwardCompatibleWithBundlesUninstalledInFifoOrder() + { + string providerId = BundleAProviderId; + string parent = "~BundleAv1"; + string parentSwitch = String.Concat("-parent ", parent); + + var packageAv1 = this.CreatePackageInstaller("PackageAv1"); + var packageAv2 = this.CreatePackageInstaller("PackageAv2"); + var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); + var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + + bundleAv2.Install(); + bundleAv2.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + + // Install the v1 bundle with a parent which should passthrough to v2. + bundleAv1.Install(arguments: parentSwitch); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + + bundleAv2.Uninstall(); + bundleAv2.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + + // Uninstall the v1 bundle with passthrough and all should be removed. + bundleAv1.Uninstall(arguments: parentSwitch); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + } + + [Fact] + public void CanUninstallForwardCompatibleWithBundlesUninstalledInReverseOrder() + { + string providerId = BundleAProviderId; + string parent = "~BundleAv1"; + string parentSwitch = String.Concat("-parent ", parent); + + var packageAv1 = this.CreatePackageInstaller("PackageAv1"); + var packageAv2 = this.CreatePackageInstaller("PackageAv2"); + var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); + var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + + bundleAv2.Install(); + bundleAv2.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion)); + Assert.Equal(V200, actualProviderVersion); + + // Install the v1 bundle with a parent which should passthrough to v2. + bundleAv1.Install(arguments: parentSwitch); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); + + // Uninstall the v1 bundle with the same parent which should passthrough to v2 and remove parent. + bundleAv1.Uninstall(arguments: parentSwitch); + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + bundleAv2.VerifyRegisteredAndInPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(true); + Assert.False(BundleRegistration.DependencyDependentExists(providerId, parent)); + + // Uninstall the v2 bundle and all should be removed. + bundleAv2.Uninstall(); + bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache(); + + packageAv1.VerifyInstalled(false); + packageAv2.VerifyInstalled(false); + Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); + } + } +} -- cgit v1.2.3-55-g6feb