DSCv3PackageResourceCommand.cs (24554B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="DSCv3PackageResourceCommand.cs" company="Microsoft Corporation"> 3 // Copyright (c) Microsoft Corporation. Licensed under the MIT License. 4 // </copyright> 5 // ----------------------------------------------------------------------------- 6 7 namespace AppInstallerCLIE2ETests 8 { 9 using System.Collections.Generic; 10 using System.Text.Json.Serialization; 11 using AppInstallerCLIE2ETests.Helpers; 12 using NUnit.Framework; 13 14 /// <summary> 15 /// `Configure` command tests. 16 /// </summary> 17 [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1010:Opening square brackets should be spaced correctly", Justification = "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release")] 18 [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1011:Closing square brackets should be spaced correctly", Justification = "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release")] 19 public class DSCv3PackageResourceCommand : DSCv3ResourceTestBase 20 { 21 private const string DefaultPackageIdentifier = Constants.ExeInstallerPackageId; 22 private const string DefaultPackageLowVersion = "1.0.0.0"; 23 private const string DefaultPackageMidVersion = "1.1.0.0"; 24 private const string DefaultPackageHighVersion = "2.0.0.0"; 25 private const string PackageResource = "package"; 26 private const string VersionPropertyName = "version"; 27 private const string UseLatestPropertyName = "useLatest"; 28 29 /// <summary> 30 /// Setup done once before all the tests here. 31 /// </summary> 32 [OneTimeSetUp] 33 public void OneTimeSetup() 34 { 35 TestCommon.SetupTestSource(); 36 WinGetSettingsHelper.ConfigureLoggingLevel("verbose"); 37 EnsureTestResourcePresence(); 38 } 39 40 /// <summary> 41 /// Teardown done once after all the tests here. 42 /// </summary> 43 [OneTimeTearDown] 44 public void OneTimeTeardown() 45 { 46 RemoveTestPackage(); 47 WinGetSettingsHelper.ConfigureLoggingLevel(null); 48 TestCommon.TearDownTestSource(); 49 } 50 51 /// <summary> 52 /// Set up. 53 /// </summary> 54 [SetUp] 55 public void Setup() 56 { 57 // Try clean up TestExeInstaller for failure cases where cleanup is not successful 58 RemoveTestPackage(); 59 } 60 61 /// <summary> 62 /// Calls `get` on the `package` resource with the value not present. 63 /// </summary> 64 [Test] 65 public void Package_Get_NotPresent() 66 { 67 PackageResourceData packageResourceData = new PackageResourceData() { Identifier = DefaultPackageIdentifier }; 68 69 var result = RunDSCv3Command(PackageResource, GetFunction, packageResourceData); 70 AssertSuccessfulResourceRun(ref result); 71 72 PackageResourceData output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut); 73 Assert.IsNotNull(output); 74 Assert.False(output.Exist); 75 Assert.AreEqual(packageResourceData.Identifier, output.Identifier); 76 } 77 78 /// <summary> 79 /// Calls `get` on the `package` resource with the package not existing. 80 /// </summary> 81 [Test] 82 public void Package_Get_UnknownIdentifier() 83 { 84 PackageResourceData packageResourceData = new PackageResourceData() { Identifier = "Not.An.Existing.Identifier.123456789.ABCDEFG" }; 85 86 var result = RunDSCv3Command(PackageResource, GetFunction, packageResourceData); 87 AssertSuccessfulResourceRun(ref result); 88 89 PackageResourceData output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut); 90 Assert.IsNotNull(output); 91 Assert.False(output.Exist); 92 Assert.AreEqual(packageResourceData.Identifier, output.Identifier); 93 } 94 95 /// <summary> 96 /// Calls `get` on the `package` resource with the value present. 97 /// </summary> 98 [Test] 99 public void Package_Get_Present() 100 { 101 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}"); 102 Assert.AreEqual(0, setupInstall.ExitCode); 103 104 PackageResourceData packageResourceData = new PackageResourceData() { Identifier = DefaultPackageIdentifier }; 105 106 var result = RunDSCv3Command(PackageResource, GetFunction, packageResourceData); 107 AssertSuccessfulResourceRun(ref result); 108 109 PackageResourceData output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut); 110 AssertExistingPackageResourceData(output, DefaultPackageLowVersion); 111 } 112 113 /// <summary> 114 /// Calls `get` on the `package` resource with the value present and supplying most inputs. 115 /// </summary> 116 [Test] 117 public void Package_Get_MuchInput() 118 { 119 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}"); 120 Assert.AreEqual(0, setupInstall.ExitCode); 121 122 PackageResourceData packageResourceData = new PackageResourceData() 123 { 124 Identifier = DefaultPackageIdentifier, 125 Source = Constants.TestSourceName, 126 MatchOption = "equals", 127 }; 128 129 var result = RunDSCv3Command(PackageResource, GetFunction, packageResourceData); 130 AssertSuccessfulResourceRun(ref result); 131 132 PackageResourceData output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut); 133 AssertExistingPackageResourceData(output, DefaultPackageLowVersion); 134 } 135 136 /// <summary> 137 /// Calls `test` on the `package` resource with the value not present. 138 /// </summary> 139 [Test] 140 public void Package_Test_NotPresent() 141 { 142 PackageResourceData packageResourceData = new PackageResourceData() { Identifier = DefaultPackageIdentifier }; 143 144 var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData); 145 AssertSuccessfulResourceRun(ref result); 146 147 (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 148 Assert.IsNotNull(output); 149 Assert.False(output.Exist); 150 Assert.AreEqual(packageResourceData.Identifier, output.Identifier); 151 Assert.False(output.InDesiredState); 152 153 AssertDiffState(diff, [ ExistPropertyName ]); 154 } 155 156 /// <summary> 157 /// Calls `test` on the `package` resource with the value present. 158 /// </summary> 159 [Test] 160 public void Package_Test_SimplePresent() 161 { 162 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}"); 163 Assert.AreEqual(0, setupInstall.ExitCode); 164 165 PackageResourceData packageResourceData = new PackageResourceData() { Identifier = DefaultPackageIdentifier }; 166 167 var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData); 168 AssertSuccessfulResourceRun(ref result); 169 170 (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 171 AssertExistingPackageResourceData(output, DefaultPackageLowVersion); 172 Assert.True(output.InDesiredState); 173 174 AssertDiffState(diff, []); 175 } 176 177 /// <summary> 178 /// Calls `test` on the `package` resource with a version that matches. 179 /// </summary> 180 [Test] 181 public void Package_Test_VersionMatch() 182 { 183 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}"); 184 Assert.AreEqual(0, setupInstall.ExitCode); 185 186 PackageResourceData packageResourceData = new PackageResourceData() 187 { 188 Identifier = DefaultPackageIdentifier, 189 Version = DefaultPackageLowVersion, 190 }; 191 192 var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData); 193 AssertSuccessfulResourceRun(ref result); 194 195 (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 196 AssertExistingPackageResourceData(output, DefaultPackageLowVersion); 197 Assert.True(output.InDesiredState); 198 199 AssertDiffState(diff, []); 200 } 201 202 /// <summary> 203 /// Calls `test` on the `package` resource with a version that does not match. 204 /// </summary> 205 [Test] 206 public void Package_Test_VersionMismatch() 207 { 208 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}"); 209 Assert.AreEqual(0, setupInstall.ExitCode); 210 211 PackageResourceData packageResourceData = new PackageResourceData() 212 { 213 Identifier = DefaultPackageIdentifier, 214 Version = DefaultPackageMidVersion, 215 }; 216 217 var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData); 218 AssertSuccessfulResourceRun(ref result); 219 220 (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 221 AssertExistingPackageResourceData(output, DefaultPackageLowVersion); 222 Assert.False(output.InDesiredState); 223 224 AssertDiffState(diff, [ VersionPropertyName ]); 225 } 226 227 /// <summary> 228 /// Calls `test` on the `package` resource with a version that is the latest. 229 /// </summary> 230 [Test] 231 public void Package_Test_Latest() 232 { 233 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier}"); 234 Assert.AreEqual(0, setupInstall.ExitCode); 235 236 PackageResourceData packageResourceData = new PackageResourceData() 237 { 238 Identifier = DefaultPackageIdentifier, 239 UseLatest = true, 240 }; 241 242 var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData); 243 AssertSuccessfulResourceRun(ref result); 244 245 (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 246 AssertExistingPackageResourceData(output, DefaultPackageHighVersion); 247 Assert.True(output.InDesiredState); 248 249 AssertDiffState(diff, []); 250 } 251 252 /// <summary> 253 /// Calls `test` on the `package` resource with a version that is not the latest. 254 /// </summary> 255 [Test] 256 public void Package_Test_NotLatest() 257 { 258 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier} --version {DefaultPackageMidVersion}"); 259 Assert.AreEqual(0, setupInstall.ExitCode); 260 261 PackageResourceData packageResourceData = new PackageResourceData() 262 { 263 Identifier = DefaultPackageIdentifier, 264 UseLatest = true, 265 }; 266 267 var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData); 268 AssertSuccessfulResourceRun(ref result); 269 270 (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 271 AssertExistingPackageResourceData(output, DefaultPackageMidVersion); 272 Assert.False(output.InDesiredState); 273 274 AssertDiffState(diff, [ UseLatestPropertyName ]); 275 } 276 277 /// <summary> 278 /// Calls `set` on the `package` resource when the package is not present, and again afterward. 279 /// </summary> 280 [Test] 281 public void Package_Set_SimpleRepeated() 282 { 283 PackageResourceData packageResourceData = new PackageResourceData() 284 { 285 Identifier = DefaultPackageIdentifier, 286 }; 287 288 var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData); 289 AssertSuccessfulResourceRun(ref result); 290 291 (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 292 AssertExistingPackageResourceData(output, DefaultPackageHighVersion, ignoreLatest: true); 293 294 AssertDiffState(diff, [ ExistPropertyName ]); 295 296 // Set again should be a no-op 297 result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData); 298 AssertSuccessfulResourceRun(ref result); 299 300 (output, diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 301 AssertExistingPackageResourceData(output, DefaultPackageHighVersion); 302 303 AssertDiffState(diff, []); 304 } 305 306 /// <summary> 307 /// Calls `set` on the `package` resource to ensure that it is not present. 308 /// </summary> 309 [Test] 310 public void Package_Set_Remove() 311 { 312 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier}"); 313 Assert.AreEqual(0, setupInstall.ExitCode); 314 315 PackageResourceData packageResourceData = new PackageResourceData() 316 { 317 Identifier = DefaultPackageIdentifier, 318 Exist = false, 319 }; 320 321 var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData); 322 AssertSuccessfulResourceRun(ref result); 323 324 (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 325 Assert.IsNotNull(output); 326 Assert.False(output.Exist); 327 Assert.AreEqual(packageResourceData.Identifier, output.Identifier); 328 329 AssertDiffState(diff, [ ExistPropertyName ]); 330 331 // Call `get` to ensure the result 332 PackageResourceData packageResourceDataForGet = new PackageResourceData() 333 { 334 Identifier = DefaultPackageIdentifier, 335 }; 336 337 result = RunDSCv3Command(PackageResource, GetFunction, packageResourceDataForGet); 338 AssertSuccessfulResourceRun(ref result); 339 340 output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut); 341 Assert.IsNotNull(output); 342 Assert.False(output.Exist); 343 Assert.AreEqual(packageResourceDataForGet.Identifier, output.Identifier); 344 } 345 346 /// <summary> 347 /// Calls `set` on the `package` resource to request the latest version when a lower version is installed. 348 /// </summary> 349 [Test] 350 public void Package_Set_Latest() 351 { 352 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier} --version {DefaultPackageMidVersion}"); 353 Assert.AreEqual(0, setupInstall.ExitCode); 354 355 PackageResourceData packageResourceData = new PackageResourceData() 356 { 357 Identifier = DefaultPackageIdentifier, 358 UseLatest = true, 359 }; 360 361 var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData); 362 AssertSuccessfulResourceRun(ref result); 363 364 (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 365 AssertExistingPackageResourceData(output, DefaultPackageHighVersion, ignoreLatest: true); 366 367 AssertDiffState(diff, [ UseLatestPropertyName ]); 368 369 // Call `get` to ensure the result 370 PackageResourceData packageResourceDataForGet = new PackageResourceData() 371 { 372 Identifier = DefaultPackageIdentifier, 373 }; 374 375 result = RunDSCv3Command(PackageResource, GetFunction, packageResourceDataForGet); 376 AssertSuccessfulResourceRun(ref result); 377 378 output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut); 379 AssertExistingPackageResourceData(output, DefaultPackageHighVersion); 380 } 381 382 /// <summary> 383 /// Calls `set` on the `package` resource to request a specific version when a lower version is installed. 384 /// </summary> 385 [Test] 386 public void Package_Set_SpecificVersionUpgrade() 387 { 388 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}"); 389 Assert.AreEqual(0, setupInstall.ExitCode); 390 391 PackageResourceData packageResourceData = new PackageResourceData() 392 { 393 Identifier = DefaultPackageIdentifier, 394 Version = DefaultPackageMidVersion, 395 }; 396 397 var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData); 398 AssertSuccessfulResourceRun(ref result); 399 400 (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 401 AssertExistingPackageResourceData(output, DefaultPackageMidVersion, ignoreLatest: true); 402 403 AssertDiffState(diff, [ VersionPropertyName ]); 404 405 // Call `get` to ensure the result 406 PackageResourceData packageResourceDataForGet = new PackageResourceData() 407 { 408 Identifier = DefaultPackageIdentifier, 409 }; 410 411 result = RunDSCv3Command(PackageResource, GetFunction, packageResourceDataForGet); 412 AssertSuccessfulResourceRun(ref result); 413 414 output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut); 415 AssertExistingPackageResourceData(output, DefaultPackageMidVersion); 416 } 417 418 /// <summary> 419 /// Calls `set` on the `package` resource to request a specific version when a higher version is installed. 420 /// </summary> 421 [Test] 422 public void Package_Set_SpecificVersionDowngrade() 423 { 424 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier}"); 425 Assert.AreEqual(0, setupInstall.ExitCode); 426 427 PackageResourceData packageResourceData = new PackageResourceData() 428 { 429 Identifier = DefaultPackageIdentifier, 430 Version = DefaultPackageMidVersion, 431 }; 432 433 var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData); 434 AssertSuccessfulResourceRun(ref result); 435 436 (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut); 437 AssertExistingPackageResourceData(output, DefaultPackageMidVersion, ignoreLatest: true); 438 439 AssertDiffState(diff, [ VersionPropertyName ]); 440 441 // Call `get` to ensure the result 442 PackageResourceData packageResourceDataForGet = new PackageResourceData() 443 { 444 Identifier = DefaultPackageIdentifier, 445 }; 446 447 result = RunDSCv3Command(PackageResource, GetFunction, packageResourceDataForGet); 448 AssertSuccessfulResourceRun(ref result); 449 450 output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut); 451 AssertExistingPackageResourceData(output, DefaultPackageMidVersion); 452 } 453 454 /// <summary> 455 /// Calls `export` on the `package` resource without providing any input. 456 /// </summary> 457 [Test] 458 public void Package_Export_NoInput() 459 { 460 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier}"); 461 Assert.AreEqual(0, setupInstall.ExitCode); 462 463 var result = RunDSCv3Command(PackageResource, ExportFunction, " "); 464 AssertSuccessfulResourceRun(ref result); 465 466 List<PackageResourceData> output = GetOutputLinesAs<PackageResourceData>(result.StdOut); 467 468 bool foundDefaultPackage = false; 469 foreach (PackageResourceData item in output) 470 { 471 if (item.Identifier == DefaultPackageIdentifier) 472 { 473 foundDefaultPackage = true; 474 Assert.IsNull(item.Version); 475 break; 476 } 477 } 478 479 Assert.IsTrue(foundDefaultPackage); 480 } 481 482 /// <summary> 483 /// Calls `export` on the `package` resource providing input to request that versions be included. 484 /// </summary> 485 [Test] 486 public void Package_Export_RequestVersions() 487 { 488 var setupInstall = TestCommon.RunAICLICommand("install", $"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}"); 489 Assert.AreEqual(0, setupInstall.ExitCode); 490 491 PackageResourceData packageResourceData = new PackageResourceData() 492 { 493 UseLatest = false, 494 }; 495 496 var result = RunDSCv3Command(PackageResource, ExportFunction, packageResourceData, 300000); 497 AssertSuccessfulResourceRun(ref result); 498 499 List<PackageResourceData> output = GetOutputLinesAs<PackageResourceData>(result.StdOut); 500 501 bool foundDefaultPackage = false; 502 foreach (PackageResourceData item in output) 503 { 504 if (item.Identifier == DefaultPackageIdentifier) 505 { 506 foundDefaultPackage = true; 507 Assert.AreEqual(DefaultPackageLowVersion, item.Version); 508 } 509 else 510 { 511 Assert.IsNotNull(item.Version); 512 Assert.IsNotEmpty(item.Version); 513 } 514 } 515 516 Assert.IsTrue(foundDefaultPackage); 517 } 518 519 private static void RemoveTestPackage() 520 { 521 PackageResourceData packageResourceData = new PackageResourceData() 522 { 523 Identifier = DefaultPackageIdentifier, 524 Exist = false, 525 }; 526 527 var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData); 528 AssertSuccessfulResourceRun(ref result); 529 } 530 531 private static void AssertExistingPackageResourceData(PackageResourceData output, string version, bool ignoreLatest = false) 532 { 533 Assert.IsNotNull(output); 534 Assert.True(output.Exist); 535 Assert.AreEqual(DefaultPackageIdentifier, output.Identifier); 536 Assert.AreEqual(version, output.Version); 537 538 if (!ignoreLatest) 539 { 540 if (version == DefaultPackageHighVersion) 541 { 542 Assert.True(output.UseLatest); 543 } 544 else 545 { 546 Assert.False(output.UseLatest); 547 } 548 } 549 } 550 551 private class PackageResourceData 552 { 553 [JsonPropertyName(ExistPropertyName)] 554 public bool? Exist { get; set; } 555 556 [JsonPropertyName(InDesiredStatePropertyName)] 557 public bool? InDesiredState { get; set; } 558 559 [JsonPropertyName("id")] 560 public string Identifier { get; set; } 561 562 public string Source { get; set; } 563 564 public string Version { get; set; } 565 566 public string MatchOption { get; set; } 567 568 public bool? UseLatest { get; set; } 569 570 public string InstallMode { get; set; } 571 572 public bool? AcceptAgreements { get; set; } 573 } 574 } 575 }