UpgradeInterop.cs (18178B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="UpgradeInterop.cs" company="Microsoft Corporation"> 3 // Copyright (c) Microsoft Corporation. Licensed under the MIT License. 4 // </copyright> 5 // ----------------------------------------------------------------------------- 6 7 namespace AppInstallerCLIE2ETests.Interop 8 { 9 using System; 10 using System.Collections.Generic; 11 using System.IO; 12 using System.Linq; 13 using System.Threading.Tasks; 14 using AppInstallerCLIE2ETests.Helpers; 15 using Microsoft.Management.Deployment; 16 using Microsoft.Management.Deployment.Projection; 17 using NUnit.Framework; 18 19 /// <summary> 20 /// Test upgrade interop. 21 /// </summary> 22 [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.InProcess), Category = nameof(InstanceInitializersSource.InProcess))] 23 [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))] 24 public class UpgradeInterop : BaseInterop 25 { 26 private PackageManager packageManager; 27 private PackageCatalogReference compositeSource; 28 29 /// <summary> 30 /// Initializes a new instance of the <see cref="UpgradeInterop"/> class. 31 /// </summary> 32 /// <param name="initializer">Initializer.</param> 33 public UpgradeInterop(IInstanceInitializer initializer) 34 : base(initializer) 35 { 36 } 37 38 /// <summary> 39 /// Set up. 40 /// </summary> 41 [SetUp] 42 public void Init() 43 { 44 this.packageManager = this.TestFactory.CreatePackageManager(); 45 46 // Create composite package catalog source 47 var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions(); 48 var testSource = this.packageManager.GetPackageCatalogByName(Constants.TestSourceName); 49 Assert.NotNull(testSource, $"{Constants.TestSourceName} cannot be null"); 50 options.Catalogs.Add(testSource); 51 options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs; 52 this.compositeSource = this.packageManager.CreateCompositePackageCatalog(options); 53 } 54 55 /// <summary> 56 /// Tests upgrade portable package. 57 /// </summary> 58 /// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns> 59 [Test] 60 public async Task UpgradePortable() 61 { 62 string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), "Microsoft", "WinGet", "Packages"); 63 string packageId = Constants.PortableExePackageId; 64 string packageDirName = Constants.PortableExePackageDirName; 65 string productCode = Constants.PortableExePackageDirName; 66 string commandAlias = Constants.AppInstallerTestExeInstallerExe; 67 string fileName = Constants.AppInstallerTestExeInstallerExe; 68 69 // Find package 70 var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 71 72 // Configure install options 73 var installOptions = this.TestFactory.CreateInstallOptions(); 74 installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "1.0.0.0"); 75 76 // Install 77 var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); 78 Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); 79 80 // Find package again, but this time it should detect the installed version 81 searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 82 Assert.AreEqual("1.0.0.0", searchResult.CatalogPackage.InstalledVersion?.Version); 83 84 // Configure upgrade options 85 var upgradeOptions = this.TestFactory.CreateInstallOptions(); 86 upgradeOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "2.0.0.0"); 87 88 // Upgrade 89 var upgradeResult = await this.packageManager.UpgradePackageAsync(searchResult.CatalogPackage, upgradeOptions); 90 Assert.AreEqual(InstallResultStatus.Ok, upgradeResult.Status); 91 92 // Find package again, but this time it should detect the upgraded installed version 93 searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 94 Assert.AreEqual("2.0.0.0", searchResult.CatalogPackage.InstalledVersion?.Version); 95 TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); 96 } 97 98 /// <summary> 99 /// Test upgrade portable package with arp mismatch. 100 /// </summary> 101 /// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns> 102 [Test] 103 public async Task UpgradePortableARPMismatch() 104 { 105 string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), "Microsoft", "WinGet", "Packages"); 106 string packageId = Constants.PortableExePackageId; 107 string packageDirName = Constants.PortableExePackageDirName; 108 string productCode = Constants.PortableExePackageDirName; 109 string commandAlias = Constants.AppInstallerTestExeInstallerExe; 110 string fileName = Constants.AppInstallerTestExeInstallerExe; 111 112 // Find package 113 var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 114 115 // Configure install options 116 var installOptions = this.TestFactory.CreateInstallOptions(); 117 installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "1.0.0.0"); 118 119 // Install 120 var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); 121 Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); 122 123 // Modify packageId to cause mismatch. 124 TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, "testPackageId"); 125 126 // Find package again, but this time it should detect the installed version 127 searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 128 Assert.NotNull(searchResult.CatalogPackage.InstalledVersion); 129 130 // Configure upgrade options 131 var upgradeOptions = this.TestFactory.CreateInstallOptions(); 132 upgradeOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "2.0.0.0"); 133 134 // Upgrade 135 var upgradeResult = await this.packageManager.UpgradePackageAsync(searchResult.CatalogPackage, upgradeOptions); 136 Assert.AreEqual(InstallResultStatus.InstallError, upgradeResult.Status); 137 Assert.AreEqual(Constants.ErrorCode.ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS, upgradeResult.ExtendedErrorCode.HResult); 138 139 // Find package again, it should have not been upgraded 140 searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 141 Assert.AreEqual("1.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); 142 TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); 143 } 144 145 /// <summary> 146 /// Test upgrade portable package force. 147 /// </summary> 148 /// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns> 149 [Test] 150 public async Task UpgradePortableForcedOverride() 151 { 152 string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), "Microsoft", "WinGet", "Packages"); 153 string packageId = Constants.PortableExePackageId; 154 string packageDirName = Constants.PortableExePackageDirName; 155 string productCode = Constants.PortableExePackageDirName; 156 string commandAlias = Constants.AppInstallerTestExeInstallerExe; 157 string fileName = Constants.AppInstallerTestExeInstallerExe; 158 159 // Find package 160 var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 161 162 // Configure install options 163 var installOptions = this.TestFactory.CreateInstallOptions(); 164 installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "1.0.0.0"); 165 166 // Install 167 var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); 168 Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); 169 170 // Modify packageId and sourceId to cause mismatch. 171 TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, "testPackageId"); 172 TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetSourceIdentifier, "testSourceId"); 173 174 // Find package again, but this time it should detect the installed version 175 searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 176 Assert.NotNull(searchResult.CatalogPackage.InstalledVersion); 177 178 // Configure upgrade options 179 var upgradeOptions = this.TestFactory.CreateInstallOptions(); 180 upgradeOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "2.0.0.0"); 181 upgradeOptions.Force = true; 182 183 // Upgrade 184 var upgradeResult = await this.packageManager.UpgradePackageAsync(searchResult.CatalogPackage, upgradeOptions); 185 Assert.AreEqual(InstallResultStatus.Ok, upgradeResult.Status); 186 187 // Find package again, but this time it should detect the upgraded installed version 188 searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 189 Assert.AreEqual("2.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); 190 TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); 191 } 192 193 /// <summary> 194 /// Test upgrade portable package uninstall previous. 195 /// </summary> 196 /// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns> 197 [Test] 198 public async Task UpgradePortableUninstallPrevious() 199 { 200 string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), "Microsoft", "WinGet", "Packages"); 201 string packageId = Constants.PortableExePackageId; 202 string packageDirName = Constants.PortableExePackageDirName; 203 string productCode = Constants.PortableExePackageDirName; 204 string commandAlias = Constants.AppInstallerTestExeInstallerExe; 205 string fileName = Constants.AppInstallerTestExeInstallerExe; 206 207 // Find package 208 var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 209 210 // Configure install options 211 var installOptions = this.TestFactory.CreateInstallOptions(); 212 installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "1.0.0.0"); 213 214 // Install 215 var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); 216 Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); 217 218 // Find package again, but this time it should detect the installed version 219 searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 220 Assert.AreEqual("1.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); 221 222 // Configure upgrade options 223 var upgradeOptions = this.TestFactory.CreateInstallOptions(); 224 upgradeOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "3.0.0.0"); 225 226 // Upgrade 227 var upgradeResult = await this.packageManager.UpgradePackageAsync(searchResult.CatalogPackage, upgradeOptions); 228 Assert.AreEqual(InstallResultStatus.Ok, upgradeResult.Status); 229 230 // Find package again, but this time it should detect the upgraded installed version 231 searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); 232 Assert.AreEqual("3.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); 233 TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); 234 } 235 236 /// <summary> 237 /// Tests IsUpdateAvailable. 238 /// </summary> 239 /// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns> 240 [Test] 241 public async Task TestIsUpdateAvailable_ApplicableTrue() 242 { 243 // Find and install the test package. Install the version 1.0.0.0. 244 var installDir = TestCommon.GetRandomTestDir(); 245 var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestExeInstaller"); 246 var installOptions = this.TestFactory.CreateInstallOptions(); 247 installOptions.PreferredInstallLocation = installDir; 248 installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "1.0.0.0"); 249 var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); 250 Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); 251 252 // Find package again, but this time it should detect the installed version. 253 searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestExeInstaller"); 254 255 // The installed version is 1.0.0.0. 256 Assert.AreEqual("1.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); 257 258 // IsUpdateAvailable is true. 259 Assert.True(searchResult.CatalogPackage.IsUpdateAvailable); 260 261 // Uninstall to clean up. 262 var uninstallOptions = this.TestFactory.CreateUninstallOptions(); 263 var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, uninstallOptions); 264 } 265 266 /// <summary> 267 /// Tests applicability check is performed for IsUpdateAvailable api. 268 /// </summary> 269 /// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns> 270 [Test] 271 public async Task TestIsUpdateAvailable_ApplicableFalse() 272 { 273 // Find and install the test package. Install the version 1.0.0.0. 274 var installDir = TestCommon.GetRandomTestDir(); 275 var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestUpgradeApplicability"); 276 var installOptions = this.TestFactory.CreateInstallOptions(); 277 installOptions.PreferredInstallLocation = installDir; 278 installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "1.0.0.0"); 279 var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); 280 Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); 281 282 // Find package again, but this time it should detect the installed version. 283 searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestUpgradeApplicability"); 284 285 // The installed version is 1.0.0.0. 286 Assert.AreEqual("1.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); 287 288 // There is version 2.0.0.0 in the package available versions. 289 Assert.NotNull(First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "2.0.0.0")); 290 291 // IsUpdateAvailable is false due to applicability check. Only arm64 in version 2.0.0.0. 292 Assert.False(searchResult.CatalogPackage.IsUpdateAvailable); 293 294 // Uninstall to clean up. 295 var uninstallOptions = this.TestFactory.CreateUninstallOptions(); 296 var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, uninstallOptions); 297 } 298 299 // Cannot use foreach or Linq for out-of-process IVector 300 // Bug: https://github.com/microsoft/CsWinRT/issues/1205 301 private static T First<T>(IReadOnlyList<T> list, Func<T, bool> condition) 302 { 303 if (list == null || condition == null) 304 { 305 throw new ArgumentNullException(); 306 } 307 308 for (int i = 0; i < list.Count; ++i) 309 { 310 var item = list[i]; 311 if (condition(item)) 312 { 313 return item; 314 } 315 } 316 317 throw new InvalidOperationException("No element satisfies the condition"); 318 } 319 } 320 }