winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

DSCv3SourceResourceCommand.cs (21528B)


      1 // -----------------------------------------------------------------------------
      2 // <copyright file="DSCv3SourceResourceCommand.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 DSCv3SourceResourceCommand : DSCv3ResourceTestBase
     20     {
     21         private const string DefaultSourceName = "SourceResourceTestSource";
     22         private const string DefaultSourceType = "Microsoft.Test.Configurable";
     23         private const string DefaultTrustLevel = "none";
     24         private const string TrustedTrustLevel = "trusted";
     25         private const bool DefaultExplicitState = false;
     26         private const string SourceResource = "source";
     27         private const string ArgumentPropertyName = "argument";
     28         private const string TypePropertyName = "type";
     29         private const string TrustLevelPropertyName = "trustLevel";
     30         private const string ExplicitPropertyName = "explicit";
     31 
     32         private static string DefaultSourceArgForCmdLine
     33         {
     34             get { return CreateSourceArgument(true); }
     35         }
     36 
     37         private static string NonDefaultSourceArgForCmdLine
     38         {
     39             get { return CreateSourceArgument(true, 1, 1); }
     40         }
     41 
     42         private static string DefaultSourceArgDirect
     43         {
     44             get { return CreateSourceArgument(false); }
     45         }
     46 
     47         private static string NonDefaultSourceArgDirect
     48         {
     49             get { return CreateSourceArgument(false, 1, 1); }
     50         }
     51 
     52         /// <summary>
     53         /// Setup done once before all the tests here.
     54         /// </summary>
     55         [OneTimeSetUp]
     56         public void OneTimeSetup()
     57         {
     58             TestCommon.SetupTestSource();
     59             EnsureTestResourcePresence();
     60         }
     61 
     62         /// <summary>
     63         /// Teardown done once after all the tests here.
     64         /// </summary>
     65         [OneTimeTearDown]
     66         public void OneTimeTeardown()
     67         {
     68             RemoveTestSource();
     69             TestCommon.TearDownTestSource();
     70         }
     71 
     72         /// <summary>
     73         /// Set up.
     74         /// </summary>
     75         [SetUp]
     76         public void Setup()
     77         {
     78             RemoveTestSource();
     79         }
     80 
     81         /// <summary>
     82         /// Calls `get` on the `source` resource with the value not present.
     83         /// </summary>
     84         [Test]
     85         public void Source_Get_NotPresent()
     86         {
     87             SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };
     88 
     89             var result = RunDSCv3Command(SourceResource, GetFunction, resourceData);
     90             AssertSuccessfulResourceRun(ref result);
     91 
     92             SourceResourceData output = GetSingleOutputLineAs<SourceResourceData>(result.StdOut);
     93             Assert.IsNotNull(output);
     94             Assert.False(output.Exist);
     95             Assert.AreEqual(resourceData.Name, output.Name);
     96         }
     97 
     98         /// <summary>
     99         /// Calls `get` on the `source` resource with the value present.
    100         /// </summary>
    101         [Test]
    102         public void Source_Get_Present()
    103         {
    104             var setup = TestCommon.RunAICLICommand("source add", $"--name {DefaultSourceName} --arg {DefaultSourceArgForCmdLine} --type {DefaultSourceType} --explicit");
    105             Assert.AreEqual(0, setup.ExitCode);
    106 
    107             SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };
    108 
    109             var result = RunDSCv3Command(SourceResource, GetFunction, resourceData);
    110             AssertSuccessfulResourceRun(ref result);
    111 
    112             SourceResourceData output = GetSingleOutputLineAs<SourceResourceData>(result.StdOut);
    113             AssertExistingSourceResourceData(output, DefaultSourceArgDirect, DefaultTrustLevel, true);
    114         }
    115 
    116         /// <summary>
    117         /// Calls `test` on the `source` resource with the value not present.
    118         /// </summary>
    119         [Test]
    120         public void Source_Test_NotPresent()
    121         {
    122             SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };
    123 
    124             var result = RunDSCv3Command(SourceResource, TestFunction, resourceData);
    125             AssertSuccessfulResourceRun(ref result);
    126 
    127             (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);
    128             Assert.IsNotNull(output);
    129             Assert.False(output.Exist);
    130             Assert.AreEqual(resourceData.Name, output.Name);
    131             Assert.False(output.InDesiredState);
    132 
    133             AssertDiffState(diff, [ ExistPropertyName ]);
    134         }
    135 
    136         /// <summary>
    137         /// Calls `test` on the `source` resource with the value present.
    138         /// </summary>
    139         [Test]
    140         public void Source_Test_SimplePresent()
    141         {
    142             var setup = TestCommon.RunAICLICommand("source add", $"--name {DefaultSourceName} --arg {DefaultSourceArgForCmdLine} --type {DefaultSourceType}");
    143             Assert.AreEqual(0, setup.ExitCode);
    144 
    145             SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };
    146 
    147             var result = RunDSCv3Command(SourceResource, TestFunction, resourceData);
    148             AssertSuccessfulResourceRun(ref result);
    149 
    150             (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);
    151             AssertExistingSourceResourceData(output, DefaultSourceArgDirect, DefaultTrustLevel, DefaultExplicitState);
    152             Assert.True(output.InDesiredState);
    153 
    154             AssertDiffState(diff, []);
    155         }
    156 
    157         /// <summary>
    158         /// Calls `test` on the `source` resource with a argument that matches.
    159         /// </summary>
    160         /// <param name="useDefaultArgument">The argument to use when adding the existing source.</param>
    161         /// <param name="trustLevel">The trust level to use when adding the existing source.</param>
    162         /// <param name="isExplicit">The explicit state to use when adding the existing source.</param>
    163         /// <param name="targetProperty">The property to target for the test.</param>
    164         [TestCase(false, DefaultTrustLevel, true, ArgumentPropertyName)]
    165         [TestCase(true, DefaultTrustLevel, false, TypePropertyName)]
    166         [TestCase(false, TrustedTrustLevel, false, TrustLevelPropertyName)]
    167         [TestCase(true, DefaultTrustLevel, true, ExplicitPropertyName)]
    168         public void Source_Test_PropertyMatch(bool useDefaultArgument, string trustLevel, bool isExplicit, string targetProperty)
    169         {
    170             var setup = TestCommon.RunAICLICommand("source add", $"--name {DefaultSourceName} --arg {(useDefaultArgument ? DefaultSourceArgForCmdLine : NonDefaultSourceArgForCmdLine)} --type {DefaultSourceType} --trust-level {trustLevel} {(isExplicit ? "--explicit" : string.Empty)}");
    171             Assert.AreEqual(0, setup.ExitCode);
    172 
    173             SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };
    174 
    175             switch (targetProperty)
    176             {
    177                 case ArgumentPropertyName:
    178                     resourceData.Argument = useDefaultArgument ? DefaultSourceArgDirect : NonDefaultSourceArgDirect;
    179                     break;
    180                 case TypePropertyName:
    181                     resourceData.Type = DefaultSourceType;
    182                     break;
    183                 case TrustLevelPropertyName:
    184                     resourceData.TrustLevel = trustLevel;
    185                     break;
    186                 case ExplicitPropertyName:
    187                     resourceData.Explicit = isExplicit;
    188                     break;
    189                 default:
    190                     Assert.Fail($"{targetProperty} is not a handled case.");
    191                     break;
    192             }
    193 
    194             var result = RunDSCv3Command(SourceResource, TestFunction, resourceData);
    195             AssertSuccessfulResourceRun(ref result);
    196 
    197             (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);
    198             AssertExistingSourceResourceData(output, useDefaultArgument ? DefaultSourceArgDirect : NonDefaultSourceArgDirect, trustLevel, isExplicit);
    199             Assert.True(output.InDesiredState);
    200 
    201             AssertDiffState(diff, []);
    202         }
    203 
    204         /// <summary>
    205         /// Calls `test` on the `source` resource with a argument that does not match.
    206         /// </summary>
    207         /// <param name="useDefaultArgument">The argument to use when adding the existing source.</param>
    208         /// <param name="trustLevel">The trust level to use when adding the existing source.</param>
    209         /// <param name="isExplicit">The explicit state to use when adding the existing source.</param>
    210         /// <param name="targetProperty">The property to target for the test.</param>
    211         /// <param name="testValue">The value to test against.</param>
    212         [TestCase(false, DefaultTrustLevel, true, ArgumentPropertyName, true)]
    213         [TestCase(false, DefaultTrustLevel, false, TrustLevelPropertyName, TrustedTrustLevel)]
    214         [TestCase(true, DefaultTrustLevel, true, ExplicitPropertyName, false)]
    215         public void Source_Test_PropertyMismatch(bool useDefaultArgument, string trustLevel, bool isExplicit, string targetProperty, object testValue)
    216         {
    217             var setup = TestCommon.RunAICLICommand("source add", $"--name {DefaultSourceName} --arg {(useDefaultArgument ? DefaultSourceArgForCmdLine : NonDefaultSourceArgForCmdLine)} --type {DefaultSourceType} --trust-level {trustLevel} {(isExplicit ? "--explicit" : string.Empty)}");
    218             Assert.AreEqual(0, setup.ExitCode);
    219 
    220             SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };
    221 
    222             switch (targetProperty)
    223             {
    224                 case ArgumentPropertyName:
    225                     resourceData.Argument = (bool)testValue ? DefaultSourceArgDirect : NonDefaultSourceArgDirect;
    226                     break;
    227                 case TrustLevelPropertyName:
    228                     resourceData.TrustLevel = (string)testValue;
    229                     break;
    230                 case ExplicitPropertyName:
    231                     resourceData.Explicit = (bool)testValue;
    232                     break;
    233                 default:
    234                     Assert.Fail($"{targetProperty} is not a handled case.");
    235                     break;
    236             }
    237 
    238             var result = RunDSCv3Command(SourceResource, TestFunction, resourceData);
    239             AssertSuccessfulResourceRun(ref result);
    240 
    241             (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);
    242             AssertExistingSourceResourceData(output, useDefaultArgument ? DefaultSourceArgDirect : NonDefaultSourceArgDirect, trustLevel, isExplicit);
    243             Assert.False(output.InDesiredState);
    244 
    245             AssertDiffState(diff, [ targetProperty ]);
    246         }
    247 
    248         /// <summary>
    249         /// Calls `test` on the `source` resource with all properties matching.
    250         /// </summary>
    251         [Test]
    252         public void Source_Test_AllMatch()
    253         {
    254             var setup = TestCommon.RunAICLICommand("source add", $"--name {DefaultSourceName} --arg {NonDefaultSourceArgForCmdLine} --type {DefaultSourceType} --trust-level {TrustedTrustLevel} --explicit");
    255             Assert.AreEqual(0, setup.ExitCode);
    256 
    257             SourceResourceData resourceData = new SourceResourceData()
    258             {
    259                 Name = DefaultSourceName,
    260                 Argument = NonDefaultSourceArgDirect,
    261                 Type = DefaultSourceType,
    262                 TrustLevel = TrustedTrustLevel,
    263                 Explicit = true,
    264             };
    265 
    266             var result = RunDSCv3Command(SourceResource, TestFunction, resourceData);
    267             AssertSuccessfulResourceRun(ref result);
    268 
    269             (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);
    270             AssertExistingSourceResourceData(output, resourceData);
    271             Assert.True(output.InDesiredState);
    272 
    273             AssertDiffState(diff, []);
    274         }
    275 
    276         /// <summary>
    277         /// Calls `set` on the `source` resource when the source is not present, and again afterward.
    278         /// </summary>
    279         [Test]
    280         public void Source_Set_SimpleRepeated()
    281         {
    282             SourceResourceData resourceData = new SourceResourceData()
    283             {
    284                 Name = DefaultSourceName,
    285                 Argument = NonDefaultSourceArgDirect,
    286                 Type = DefaultSourceType,
    287             };
    288 
    289             var result = RunDSCv3Command(SourceResource, SetFunction, resourceData);
    290             AssertSuccessfulResourceRun(ref result);
    291 
    292             (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);
    293             AssertExistingSourceResourceData(output, resourceData);
    294 
    295             AssertDiffState(diff, [ ExistPropertyName ]);
    296 
    297             // Set again should be a no-op
    298             result = RunDSCv3Command(SourceResource, SetFunction, resourceData);
    299             AssertSuccessfulResourceRun(ref result);
    300 
    301             (output, diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);
    302             AssertExistingSourceResourceData(output, resourceData);
    303 
    304             AssertDiffState(diff, []);
    305         }
    306 
    307         /// <summary>
    308         /// Calls `set` on the `source` resource to ensure that it is not present.
    309         /// </summary>
    310         [Test]
    311         public void Source_Set_Remove()
    312         {
    313             var setup = TestCommon.RunAICLICommand("source add", $"--name {DefaultSourceName} --arg {DefaultSourceArgForCmdLine} --type {DefaultSourceType} --explicit");
    314             Assert.AreEqual(0, setup.ExitCode);
    315 
    316             SourceResourceData resourceData = new SourceResourceData()
    317             {
    318                 Name = DefaultSourceName,
    319                 Exist = false,
    320             };
    321 
    322             var result = RunDSCv3Command(SourceResource, SetFunction, resourceData);
    323             AssertSuccessfulResourceRun(ref result);
    324 
    325             (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);
    326             Assert.IsNotNull(output);
    327             Assert.False(output.Exist);
    328             Assert.AreEqual(resourceData.Name, output.Name);
    329 
    330             AssertDiffState(diff, [ ExistPropertyName ]);
    331 
    332             // Call `get` to ensure the result
    333             SourceResourceData resourceDataForGet = new SourceResourceData()
    334             {
    335                 Name = DefaultSourceName,
    336             };
    337 
    338             result = RunDSCv3Command(SourceResource, GetFunction, resourceDataForGet);
    339             AssertSuccessfulResourceRun(ref result);
    340 
    341             output = GetSingleOutputLineAs<SourceResourceData>(result.StdOut);
    342             Assert.IsNotNull(output);
    343             Assert.False(output.Exist);
    344             Assert.AreEqual(resourceDataForGet.Name, output.Name);
    345         }
    346 
    347         /// <summary>
    348         /// Calls `set` on the `source` resource with an existing item, replacing it.
    349         /// </summary>
    350         [Test]
    351         public void Source_Set_Replace()
    352         {
    353             var setup = TestCommon.RunAICLICommand("source add", $"--name {DefaultSourceName} --arg {DefaultSourceArgForCmdLine} --type {DefaultSourceType}");
    354             Assert.AreEqual(0, setup.ExitCode);
    355 
    356             SourceResourceData resourceData = new SourceResourceData()
    357             {
    358                 Name = DefaultSourceName,
    359                 Argument = DefaultSourceArgDirect,
    360                 Type = DefaultSourceType,
    361                 TrustLevel = TrustedTrustLevel,
    362                 Explicit = true,
    363             };
    364 
    365             var result = RunDSCv3Command(SourceResource, SetFunction, resourceData);
    366             AssertSuccessfulResourceRun(ref result);
    367 
    368             (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);
    369             AssertExistingSourceResourceData(output, resourceData);
    370 
    371             AssertDiffState(diff, [ TrustLevelPropertyName, ExplicitPropertyName ]);
    372 
    373             // Call `get` to ensure the result
    374             SourceResourceData resourceDataForGet = new SourceResourceData()
    375             {
    376                 Name = DefaultSourceName,
    377             };
    378 
    379             result = RunDSCv3Command(SourceResource, GetFunction, resourceDataForGet);
    380             AssertSuccessfulResourceRun(ref result);
    381 
    382             output = GetSingleOutputLineAs<SourceResourceData>(result.StdOut);
    383             AssertExistingSourceResourceData(output, resourceData);
    384         }
    385 
    386         /// <summary>
    387         /// Calls `export` on the `source` resource without providing any input.
    388         /// </summary>
    389         [Test]
    390         public void Source_Export_NoInput()
    391         {
    392             var setup = TestCommon.RunAICLICommand("source add", $"--name {DefaultSourceName} --arg {DefaultSourceArgForCmdLine} --type {DefaultSourceType}");
    393             Assert.AreEqual(0, setup.ExitCode);
    394 
    395             var result = RunDSCv3Command(SourceResource, ExportFunction, " ");
    396             AssertSuccessfulResourceRun(ref result);
    397 
    398             List<SourceResourceData> output = GetOutputLinesAs<SourceResourceData>(result.StdOut);
    399 
    400             bool foundDefaultSource = false;
    401             foreach (SourceResourceData item in output)
    402             {
    403                 if (item.Name == DefaultSourceName)
    404                 {
    405                     foundDefaultSource = true;
    406                     Assert.AreEqual(DefaultSourceName, item.Name);
    407                     Assert.AreEqual(DefaultSourceArgDirect, item.Argument);
    408                     Assert.AreEqual(DefaultSourceType, item.Type);
    409                     Assert.AreEqual(DefaultTrustLevel, item.TrustLevel);
    410                     Assert.AreEqual(DefaultExplicitState, item.Explicit);
    411                     break;
    412                 }
    413             }
    414 
    415             Assert.IsTrue(foundDefaultSource);
    416         }
    417 
    418         private static void RemoveTestSource()
    419         {
    420             SourceResourceData resourceData = new SourceResourceData()
    421             {
    422                 Name = DefaultSourceName,
    423                 Exist = false,
    424             };
    425 
    426             var result = RunDSCv3Command(SourceResource, SetFunction, resourceData);
    427             AssertSuccessfulResourceRun(ref result);
    428         }
    429 
    430         private static void AssertExistingSourceResourceData(SourceResourceData output, SourceResourceData input)
    431         {
    432             AssertExistingSourceResourceData(output, input.Argument, input.TrustLevel, input.Explicit);
    433         }
    434 
    435         private static void AssertExistingSourceResourceData(SourceResourceData output, string argument, string trustLevel = null, bool? isExplicit = null)
    436         {
    437             Assert.IsNotNull(output);
    438             Assert.True(output.Exist);
    439             Assert.AreEqual(DefaultSourceName, output.Name);
    440             Assert.AreEqual(argument, output.Argument);
    441             Assert.AreEqual(DefaultSourceType, output.Type);
    442 
    443             if (trustLevel != null)
    444             {
    445                 Assert.AreEqual(trustLevel, output.TrustLevel);
    446             }
    447 
    448             if (isExplicit != null)
    449             {
    450                 Assert.AreEqual(isExplicit, output.Explicit);
    451             }
    452         }
    453 
    454         private static string CreateSourceArgument(bool forCommandLine = false, int openHR = 0, int searchHR = 0)
    455         {
    456             const string CommandLineFormat = @"""{{""""OpenHR"""": {0}, """"SearchHR"""": {1} }}""";
    457             const string DirectFormat = @"{{""OpenHR"": {0}, ""SearchHR"": {1} }}";
    458             return string.Format(forCommandLine ? CommandLineFormat : DirectFormat, openHR, searchHR);
    459         }
    460 
    461         private class SourceResourceData
    462         {
    463             [JsonPropertyName(ExistPropertyName)]
    464             public bool? Exist { get; set; }
    465 
    466             [JsonPropertyName(InDesiredStatePropertyName)]
    467             public bool? InDesiredState { get; set; }
    468 
    469             public string Name { get; set; }
    470 
    471             public string Argument { get; set; }
    472 
    473             public string Type { get; set; }
    474 
    475             public string TrustLevel { get; set; }
    476 
    477             public bool? Explicit { get; set; }
    478 
    479             public bool? AcceptAgreements { get; set; }
    480         }
    481     }
    482 }