winget-cli

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

ConfigurationSetProcessorTests.cs (42778B)


      1 // -----------------------------------------------------------------------------
      2 // <copyright file="ConfigurationSetProcessorTests.cs" company="Microsoft Corporation">
      3 //     Copyright (c) Microsoft Corporation. Licensed under the MIT License.
      4 // </copyright>
      5 // -----------------------------------------------------------------------------
      6 
      7 namespace Microsoft.Management.Configuration.UnitTests.Tests
      8 {
      9     using System;
     10     using System.Collections.Generic;
     11     using System.Management.Automation;
     12     using Microsoft.Management.Configuration;
     13     using Microsoft.Management.Configuration.Processor.Exceptions;
     14     using Microsoft.Management.Configuration.Processor.Helpers;
     15     using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;
     16     using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;
     17     using Microsoft.Management.Configuration.Processor.PowerShell.ProcessorEnvironments;
     18     using Microsoft.Management.Configuration.Processor.PowerShell.Set;
     19     using Microsoft.Management.Configuration.UnitTests.Fixtures;
     20     using Microsoft.Management.Configuration.UnitTests.Helpers;
     21     using Microsoft.PowerShell.Commands;
     22     using Moq;
     23     using Windows.Foundation.Collections;
     24     using Windows.Security.Cryptography.Certificates;
     25     using Xunit;
     26     using Xunit.Abstractions;
     27 
     28     /// <summary>
     29     /// Unit tests for configuration processor tests.
     30     /// </summary>
     31     [Collection("UnitTestCollection")]
     32     [InProc]
     33     public class ConfigurationSetProcessorTests
     34     {
     35         private readonly UnitTestFixture fixture;
     36         private readonly ITestOutputHelper log;
     37 
     38         /// <summary>
     39         /// Initializes a new instance of the <see cref="ConfigurationSetProcessorTests"/> class.
     40         /// </summary>
     41         /// <param name="fixture">Unit test fixture.</param>
     42         /// <param name="log">Log helper.</param>
     43         public ConfigurationSetProcessorTests(UnitTestFixture fixture, ITestOutputHelper log)
     44         {
     45             this.fixture = fixture;
     46             this.log = log;
     47         }
     48 
     49         /// <summary>
     50         /// Test CreateUnitProcessor. Happy path.
     51         /// </summary>
     52         [Fact]
     53         public void CreateUnitProcessor_ResourceExists()
     54         {
     55             string resourceName = "xResourceName";
     56             string moduleName = "xModuleName";
     57             Version version = new Version("1.0");
     58 
     59             var processorEnvMock = new Mock<IProcessorEnvironment>();
     60             processorEnvMock.Setup(
     61                     m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
     62                 .Returns(new DscResourceInfoInternal(resourceName, moduleName, version))
     63                 .Verifiable();
     64 
     65             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
     66                 processorEnvMock.Object,
     67                 new ConfigurationSet());
     68 
     69             var unit = new ConfigurationUnit
     70             {
     71                 Type = resourceName,
     72             };
     73             unit.Metadata.Add("module", moduleName);
     74             unit.Metadata.Add("version", version.ToString());
     75 
     76             var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);
     77             Assert.NotNull(unitProcessor);
     78             Assert.Equal(unit.Type, unitProcessor.Unit.Type);
     79 
     80             processorEnvMock.Verify();
     81         }
     82 
     83         /// <summary>
     84         /// Test CreateUnitProcessor case-insensitive.
     85         /// </summary>
     86         [Fact]
     87         public void CreateUnitProcessor_CaseInsensitive()
     88         {
     89             string resourceName = "name";
     90             string moduleName = "xModuleName";
     91             Version version = new Version("1.0");
     92 
     93             var processorEnvMock = new Mock<IProcessorEnvironment>();
     94             processorEnvMock.Setup(
     95                     m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type.Equals("Name", StringComparison.OrdinalIgnoreCase))))
     96                 .Returns(new DscResourceInfoInternal("Name", moduleName, version))
     97                 .Verifiable();
     98 
     99             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    100                 processorEnvMock.Object,
    101                 new ConfigurationSet());
    102 
    103             var unit = new ConfigurationUnit
    104             {
    105                 Type = resourceName,
    106             };
    107             unit.Metadata.Add("module", moduleName);
    108             unit.Metadata.Add("version", version.ToString());
    109 
    110             var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);
    111             Assert.NotNull(unitProcessor);
    112             Assert.Equal(unit.Type, unitProcessor.Unit.Type);
    113 
    114             processorEnvMock.Verify();
    115         }
    116 
    117         /// <summary>
    118         /// Test CreateUnitProcessor case-insensitive.
    119         /// </summary>
    120         [Fact]
    121         public void CreateUnitProcessor_ResourceNameMismatch()
    122         {
    123             string resourceName = "name";
    124             string moduleName = "xModuleName";
    125             Version version = new Version("1.0");
    126 
    127             var processorEnvMock = new Mock<IProcessorEnvironment>();
    128             processorEnvMock.Setup(
    129                     m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    130                 .Returns(new DscResourceInfoInternal("OtherName", moduleName, version))
    131                 .Verifiable();
    132 
    133             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    134                 processorEnvMock.Object,
    135                 new ConfigurationSet());
    136 
    137             var unit = new ConfigurationUnit
    138             {
    139                 Type = resourceName,
    140             };
    141             unit.Metadata.Add("module", moduleName);
    142             unit.Metadata.Add("version", version.ToString());
    143 
    144             Assert.Throws<ArgumentException>(() => configurationSetProcessor.CreateUnitProcessor(unit));
    145 
    146             processorEnvMock.Verify();
    147         }
    148 
    149         /// <summary>
    150         /// Test CreateUnitProcessor with no version directive.
    151         /// </summary>
    152         [Fact]
    153         public void CreateUnitProcessor_ResourceExists_NoVersionDirective()
    154         {
    155             string resourceName = "xResourceName";
    156             string moduleName = "xModuleName";
    157             Version version = new Version("1.0.0.0");
    158 
    159             var processorEnvMock = new Mock<IProcessorEnvironment>();
    160             processorEnvMock.Setup(
    161                     m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    162                 .Returns(new DscResourceInfoInternal(resourceName, moduleName, version))
    163                 .Verifiable();
    164 
    165             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    166                 processorEnvMock.Object,
    167                 new ConfigurationSet());
    168 
    169             var unit = new ConfigurationUnit
    170             {
    171                 Type = resourceName,
    172             };
    173             unit.Metadata.Add("module", moduleName);
    174 
    175             var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);
    176             Assert.NotNull(unitProcessor);
    177             Assert.Equal(unit.Type, unitProcessor.Unit.Type);
    178 
    179             processorEnvMock.Verify();
    180         }
    181 
    182         /// <summary>
    183         /// Test CreateUnitProcessor with no module directive.
    184         /// </summary>
    185         [Fact]
    186         public void CreateUnitProcessor_ResourceExists_NoModuleDirective()
    187         {
    188             string resourceName = "xResourceName";
    189             string moduleName = "xModuleName";
    190             Version version = new Version("1.0");
    191 
    192             var processorEnvMock = new Mock<IProcessorEnvironment>();
    193             processorEnvMock.Setup(
    194                     m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    195                 .Returns(new DscResourceInfoInternal(resourceName, moduleName, version))
    196                 .Verifiable();
    197 
    198             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    199                 processorEnvMock.Object,
    200                 new ConfigurationSet());
    201 
    202             var unit = new ConfigurationUnit
    203             {
    204                 Type = resourceName,
    205             };
    206 
    207             var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);
    208             Assert.NotNull(unitProcessor);
    209             Assert.Equal(unit.Type, unitProcessor.Unit.Type);
    210 
    211             processorEnvMock.Verify();
    212         }
    213 
    214         /// <summary>
    215         /// Tests Creating a unit processor by downloading the resource.
    216         /// </summary>
    217         [Fact]
    218         public void CreateUnitProcessor_InstallResource()
    219         {
    220             string resourceName = "xResourceName";
    221             string moduleName = "xModuleName";
    222             Version version = new Version("1.0");
    223 
    224             DscResourceInfoInternal? nullResource = null;
    225             DscResourceInfoInternal dscResourceInfo = new DscResourceInfoInternal(resourceName, moduleName, version);
    226             var processorEnvMock = new Mock<IProcessorEnvironment>();
    227             processorEnvMock.SetupSequence(
    228                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    229                 .Returns(nullResource)
    230                 .Returns(dscResourceInfo);
    231 
    232             PSObject findDscResourceResult = new PSObject(processorEnvMock);
    233             processorEnvMock.Setup(
    234                 m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    235                 .Returns(findDscResourceResult)
    236                 .Verifiable();
    237 
    238             processorEnvMock.Setup(
    239                 m => m.InstallModule(findDscResourceResult))
    240                 .Verifiable();
    241 
    242             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    243                 processorEnvMock.Object,
    244                 new ConfigurationSet());
    245 
    246             var unit = new ConfigurationUnit
    247             {
    248                 Type = resourceName,
    249             };
    250             unit.Metadata.Add("module", moduleName);
    251             unit.Metadata.Add("version", version.ToString());
    252 
    253             var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);
    254             Assert.NotNull(unitProcessor);
    255             Assert.Equal(unit.Type, unitProcessor.Unit.Type);
    256 
    257             processorEnvMock.Verify();
    258         }
    259 
    260         /// <summary>
    261         /// Tests Creating a unit processor by downloading the resource.
    262         /// </summary>
    263         [Fact]
    264         public void CreateUnitProcessor_InstallResource_WithoutModule()
    265         {
    266             string resourceName = "SimpleFileResource";
    267             Version version = new Version("0.0.0.1");
    268 
    269             DscResourceInfoInternal? nullResource = null;
    270             DscResourceInfoInternal dscResourceInfo = new DscResourceInfoInternal(resourceName, null, version);
    271             var processorEnvMock = new Mock<IProcessorEnvironment>();
    272             processorEnvMock.SetupSequence(
    273                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    274                 .Returns(nullResource)
    275                 .Returns(dscResourceInfo);
    276 
    277             PSObject findDscResourceResult = this.CreateFindResourceInfo();
    278             processorEnvMock.Setup(
    279                 m => m.FindDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    280                 .Returns(findDscResourceResult)
    281                 .Verifiable();
    282 
    283             PSObject moduleInfo = ((dynamic)findDscResourceResult).PSGetModuleInfo;
    284             processorEnvMock.Setup(
    285                 m => m.InstallModule(moduleInfo))
    286                 .Verifiable();
    287 
    288             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    289                 processorEnvMock.Object,
    290                 new ConfigurationSet());
    291 
    292             var unit = new ConfigurationUnit
    293             {
    294                 Type = resourceName,
    295             };
    296             unit.Metadata.Add("version", version.ToString());
    297 
    298             var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);
    299             Assert.NotNull(unitProcessor);
    300             Assert.Equal(unit.Type, unitProcessor.Unit.Type);
    301 
    302             processorEnvMock.Verify();
    303         }
    304 
    305         /// <summary>
    306         /// Tests Creating a unit processor by downloading the resource.
    307         /// </summary>
    308         [Fact]
    309         public void CreateUnitProcessor_InstallResource_NotFoundAfterInstall()
    310         {
    311             string resourceName = "xResourceName";
    312             string moduleName = "xModuleName";
    313             Version version = new Version("1.0");
    314 
    315             DscResourceInfoInternal? nullResource = null;
    316             DscResourceInfoInternal dscResourceInfo = new DscResourceInfoInternal(resourceName, moduleName, version);
    317             var processorEnvMock = new Mock<IProcessorEnvironment>();
    318             processorEnvMock.Setup(
    319                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    320                 .Returns(nullResource);
    321 
    322             PSObject findDscResourceResult = new PSObject(processorEnvMock);
    323             processorEnvMock.Setup(
    324                 m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    325                 .Returns(findDscResourceResult)
    326                 .Verifiable();
    327 
    328             processorEnvMock.Setup(
    329                 m => m.InstallModule(findDscResourceResult))
    330                 .Verifiable();
    331 
    332             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    333                 processorEnvMock.Object,
    334                 new ConfigurationSet());
    335 
    336             var unit = new ConfigurationUnit
    337             {
    338                 Type = resourceName,
    339             };
    340             unit.Metadata.Add("module", moduleName);
    341             unit.Metadata.Add("version", version.ToString());
    342 
    343             Assert.Throws<InstallDscResourceException>(
    344                 () => configurationSetProcessor.CreateUnitProcessor(unit));
    345 
    346             processorEnvMock.Verify();
    347         }
    348 
    349         /// <summary>
    350         /// Tests Creating a unit processor by downloading the resource.
    351         /// </summary>
    352         [Fact]
    353         public void CreateUnitProcessor_InstallResource_NotFound()
    354         {
    355             string resourceName = "xResourceName";
    356             string moduleName = "xModuleName";
    357             Version version = new Version("1.0");
    358 
    359             DscResourceInfoInternal? nullResource = null;
    360             DscResourceInfoInternal dscResourceInfo = new DscResourceInfoInternal(resourceName, moduleName, version);
    361             var processorEnvMock = new Mock<IProcessorEnvironment>();
    362             processorEnvMock.Setup(
    363                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    364                 .Returns(nullResource);
    365 
    366             PSObject? findDscResourceResult = null;
    367             processorEnvMock.Setup(
    368                 m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    369                 .Returns(findDscResourceResult)
    370                 .Verifiable();
    371 
    372             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    373                 processorEnvMock.Object,
    374                 new ConfigurationSet());
    375 
    376             var unit = new ConfigurationUnit
    377             {
    378                 Type = resourceName,
    379             };
    380             unit.Metadata.Add("module", moduleName);
    381             unit.Metadata.Add("version", version.ToString());
    382 
    383             Assert.Throws<FindDscResourceNotFoundException>(
    384                 () => configurationSetProcessor.CreateUnitProcessor(unit));
    385 
    386             processorEnvMock.Verify();
    387         }
    388 
    389         /// <summary>
    390         /// Test GetUnitProcessorDetails Local Resource not found.
    391         /// </summary>
    392         [Fact]
    393         public void GetUnitProcessorDetails_Local_NoFound()
    394         {
    395             string resourceName = "xResource";
    396             DscResourceInfoInternal? nullDscInfoInternal = null;
    397 
    398             var processorEnvMock = new Mock<IProcessorEnvironment>();
    399             processorEnvMock.Setup(
    400                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == resourceName)))
    401                 .Returns(nullDscInfoInternal)
    402                 .Verifiable();
    403 
    404             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    405                 processorEnvMock.Object,
    406                 new ConfigurationSet());
    407 
    408             var unit = new ConfigurationUnit()
    409             {
    410                 Type = resourceName,
    411             };
    412 
    413             var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(
    414                 unit,
    415                 ConfigurationUnitDetailFlags.Local);
    416 
    417             Assert.Null(configurationUnitProcessorDetails);
    418 
    419             processorEnvMock.Verify();
    420         }
    421 
    422         /// <summary>
    423         /// Test GetUnitProcessorDetails Local Found. Module not installed by PowerShellGet.
    424         /// </summary>
    425         [Fact]
    426         public void GetUnitProcessorDetails_Local_NotInstalledByPowerShellGet()
    427         {
    428             var unit = this.CreateConfigurationUnit();
    429             var (dscResourceInfo, psModuleInfo) = this.GetResourceAndModuleInfo(unit);
    430             PSObject? nullPsModuleInfo = null;
    431 
    432             var processorEnvMock = new Mock<IProcessorEnvironment>();
    433             processorEnvMock.Setup(
    434                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == dscResourceInfo.Name)))
    435                 .Returns(dscResourceInfo)
    436                 .Verifiable();
    437             processorEnvMock.Setup(
    438                 m => m.GetAvailableModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))
    439                 .Returns(psModuleInfo)
    440                 .Verifiable();
    441             processorEnvMock.Setup(
    442                 m => m.GetInstalledModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))
    443                 .Returns(nullPsModuleInfo)
    444                 .Verifiable();
    445             processorEnvMock.Setup(
    446                 m => m.GetCertsOfValidSignedFiles(It.IsAny<string[]>()))
    447                 .Returns(new List<Certificate>())
    448                 .Verifiable();
    449 
    450             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    451                 processorEnvMock.Object,
    452                 new ConfigurationSet());
    453 
    454             var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(
    455                 unit,
    456                 ConfigurationUnitDetailFlags.Local);
    457 
    458             Assert.NotNull(configurationUnitProcessorDetails);
    459             Assert.Equal(dscResourceInfo.Name, configurationUnitProcessorDetails.UnitType);
    460 
    461             processorEnvMock.Verify();
    462         }
    463 
    464         /// <summary>
    465         /// Test GetUnitProcessorDetails locally found. Do not include Load.
    466         /// </summary>
    467         /// <param name="detailFlags">Detail flags.</param>
    468         [Theory]
    469         [InlineData(ConfigurationUnitDetailFlags.Local)]
    470         [InlineData(ConfigurationUnitDetailFlags.ReadOnly)]
    471         [InlineData(ConfigurationUnitDetailFlags.Download)]
    472         public void GetUnitProcessorDetails_Local(object detailFlags)
    473         {
    474             var unit = this.CreateConfigurationUnit();
    475             var (dscResourceInfo, psModuleInfo) = this.GetResourceAndModuleInfo(unit);
    476             var getModuleInfo = this.CreateGetModuleInfo();
    477 
    478             var processorEnvMock = new Mock<IProcessorEnvironment>();
    479             processorEnvMock.Setup(
    480                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == dscResourceInfo.Name)))
    481                 .Returns(dscResourceInfo)
    482                 .Verifiable();
    483             processorEnvMock.Setup(
    484                 m => m.GetAvailableModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))
    485                 .Returns(psModuleInfo)
    486                 .Verifiable();
    487             processorEnvMock.Setup(
    488                 m => m.GetInstalledModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))
    489                 .Returns(getModuleInfo)
    490                 .Verifiable();
    491             processorEnvMock.Setup(
    492                 m => m.GetCertsOfValidSignedFiles(It.IsAny<string[]>()))
    493                 .Returns(new List<Certificate>())
    494                 .Verifiable();
    495 
    496             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    497                 processorEnvMock.Object,
    498                 new ConfigurationSet());
    499 
    500             var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(
    501                 unit,
    502                 Assert.IsType<ConfigurationUnitDetailFlags>(detailFlags));
    503 
    504             Assert.NotNull(configurationUnitProcessorDetails);
    505             Assert.Equal(dscResourceInfo.Name, configurationUnitProcessorDetails.UnitType);
    506 
    507             processorEnvMock.Verify();
    508             processorEnvMock.Verify(m => m.FindDscResource(It.IsAny<ConfigurationUnitAndModule>()), Times.Never());
    509             processorEnvMock.Verify(m => m.ImportModule(It.IsAny<ModuleSpecification>()), Times.Never());
    510         }
    511 
    512         /// <summary>
    513         /// Test GetUnitProcessorDetails locally found and load.
    514         /// </summary>
    515         [Fact]
    516         public void GetUnitProcessorDetails_Local_Load()
    517         {
    518             var unit = this.CreateConfigurationUnit();
    519             var (dscResourceInfo, psModuleInfo) = this.GetResourceAndModuleInfo(unit);
    520             var getModuleInfo = this.CreateGetModuleInfo();
    521 
    522             var processorEnvMock = new Mock<IProcessorEnvironment>();
    523             processorEnvMock.Setup(
    524                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == dscResourceInfo.Name)))
    525                 .Returns(dscResourceInfo)
    526                 .Verifiable();
    527             processorEnvMock.Setup(
    528                 m => m.GetAvailableModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))
    529                 .Returns(psModuleInfo)
    530                 .Verifiable();
    531             processorEnvMock.Setup(
    532                 m => m.GetInstalledModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))
    533                 .Returns(getModuleInfo)
    534                 .Verifiable();
    535             processorEnvMock.Setup(
    536                 m => m.ImportModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))
    537                 .Verifiable();
    538             processorEnvMock.Setup(
    539                 m => m.GetCertsOfValidSignedFiles(It.IsAny<string[]>()))
    540                 .Returns(new List<Certificate>())
    541                 .Verifiable();
    542 
    543             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    544                 processorEnvMock.Object,
    545                 new ConfigurationSet());
    546 
    547             var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(
    548                 unit,
    549                 ConfigurationUnitDetailFlags.Load);
    550 
    551             Assert.NotNull(configurationUnitProcessorDetails);
    552             Assert.Equal(dscResourceInfo.Name, configurationUnitProcessorDetails.UnitType);
    553 
    554             processorEnvMock.Verify();
    555             processorEnvMock.Verify(m => m.FindDscResource(It.IsAny<ConfigurationUnitAndModule>()), Times.Never());
    556         }
    557 
    558         /// <summary>
    559         /// Test GetUnitProcessorDetails Catalog Not Found.
    560         /// </summary>
    561         [Fact]
    562         public void GetUnitProcessorDetails_Catalog_NotFound()
    563         {
    564             var unit = this.CreateConfigurationUnit();
    565             DscResourceInfoInternal? nullDscResourceInfo = null;
    566             PSObject? nullPsModuleInfo = null;
    567 
    568             var processorEnvMock = new Mock<IProcessorEnvironment>();
    569             processorEnvMock.Setup(
    570                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)))
    571                 .Returns(nullDscResourceInfo)
    572                 .Verifiable();
    573             processorEnvMock.Setup(
    574                 m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => unit.Type == unit.Type)))
    575                 .Returns(nullPsModuleInfo)
    576                 .Verifiable();
    577 
    578             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    579                 processorEnvMock.Object,
    580                 new ConfigurationSet());
    581 
    582             var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(
    583                 unit,
    584                 ConfigurationUnitDetailFlags.ReadOnly);
    585 
    586             Assert.Null(configurationUnitProcessorDetails);
    587 
    588             processorEnvMock.Verify();
    589         }
    590 
    591         /// <summary>
    592         /// Test GetUnitProcessorDetails Catalog Found.
    593         /// </summary>
    594         [Fact]
    595         public void GetUnitProcessorDetails_Catalog()
    596         {
    597             var unit = this.CreateConfigurationUnit();
    598             DscResourceInfoInternal? nullDscResourceInfo = null;
    599             var getFindResourceInfo = this.CreateFindResourceInfo();
    600 
    601             var processorEnvMock = new Mock<IProcessorEnvironment>();
    602             processorEnvMock.Setup(
    603                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)))
    604                 .Returns(nullDscResourceInfo)
    605                 .Verifiable();
    606             processorEnvMock.Setup(
    607                 m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => unit.Type == unit.Type)))
    608                 .Returns(getFindResourceInfo)
    609                 .Verifiable();
    610 
    611             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    612                 processorEnvMock.Object,
    613                 new ConfigurationSet());
    614 
    615             var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(
    616                 unit,
    617                 ConfigurationUnitDetailFlags.ReadOnly);
    618 
    619             Assert.NotNull(configurationUnitProcessorDetails);
    620             Assert.Equal("SimpleFileResource", configurationUnitProcessorDetails.UnitType);
    621 
    622             processorEnvMock.Verify();
    623         }
    624 
    625         /// <summary>
    626         /// Test GetUnitProcessorDetails downloading module.
    627         /// </summary>
    628         [Fact]
    629         public void GetUnitProcessorDetails_Download()
    630         {
    631             var unit = this.CreateConfigurationUnit();
    632             DscResourceInfoInternal? nullDscResourceInfo = null;
    633             var (_, psModuleInfo) = this.GetResourceAndModuleInfo(unit);
    634             var getFindModuleInfo = this.CreateGetModuleInfo();
    635 
    636             var processorEnvMock = new Mock<IProcessorEnvironment>();
    637             processorEnvMock.Setup(
    638                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)))
    639                 .Returns(nullDscResourceInfo)
    640                 .Verifiable();
    641             processorEnvMock.Setup(
    642                 m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => unit.Type == unit.Type)))
    643                 .Returns(getFindModuleInfo)
    644                 .Verifiable();
    645             processorEnvMock.Setup(
    646                 m => m.SaveModule(getFindModuleInfo, It.IsAny<string>()))
    647                 .Verifiable();
    648             processorEnvMock.Setup(
    649                 m => m.GetAvailableModule(It.Is<string>(s => s.EndsWith("xSimpleTestResource"))))
    650                 .Returns(psModuleInfo)
    651                 .Verifiable();
    652             processorEnvMock.Setup(
    653                 m => m.GetCertsOfValidSignedFiles(It.IsAny<string[]>()))
    654                 .Returns(new List<Certificate>())
    655                 .Verifiable();
    656 
    657             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    658                 processorEnvMock.Object,
    659                 new ConfigurationSet());
    660 
    661             var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(
    662                 unit,
    663                 ConfigurationUnitDetailFlags.Download);
    664 
    665             Assert.NotNull(configurationUnitProcessorDetails);
    666             Assert.Equal("SimpleFileResource", configurationUnitProcessorDetails.UnitType);
    667 
    668             processorEnvMock.Verify();
    669 
    670             processorEnvMock.Verify(m => m.InstallModule(It.IsAny<PSObject>()), Times.Never());
    671         }
    672 
    673         /// <summary>
    674         /// Tests GetUnitProcessorDetails install module, but resource not found anyway.
    675         /// </summary>
    676         [Fact]
    677         public void GetUnitProcessorDetails_Load_NotFoundAfterInstall()
    678         {
    679             var unit = this.CreateConfigurationUnit();
    680             DscResourceInfoInternal? nullDscResourceInfo = null;
    681             var (_, psModuleInfo) = this.GetResourceAndModuleInfo(unit);
    682             var getFindResourceInfo = this.CreateFindResourceInfo();
    683 
    684             var processorEnvMock = new Mock<IProcessorEnvironment>();
    685             processorEnvMock.Setup(
    686                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)))
    687                 .Returns(nullDscResourceInfo)
    688                 .Verifiable();
    689             processorEnvMock.Setup(
    690                 m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => unit.Type == unit.Type)))
    691                 .Returns(getFindResourceInfo)
    692                 .Verifiable();
    693             processorEnvMock.Setup(
    694                 m => m.InstallModule(getFindResourceInfo))
    695                 .Verifiable();
    696 
    697             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    698                 processorEnvMock.Object,
    699                 new ConfigurationSet());
    700 
    701             Assert.Throws<InstallDscResourceException>(() => configurationSetProcessor.GetUnitProcessorDetails(
    702                 unit,
    703                 ConfigurationUnitDetailFlags.Load));
    704 
    705             processorEnvMock.Verify();
    706             processorEnvMock.Verify(
    707                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)),
    708                 Times.Exactly(2));
    709         }
    710 
    711         /// <summary>
    712         /// Tests GetUnitProcessorDetails install module.
    713         /// </summary>
    714         [Fact]
    715         public void GetUnitProcessorDetails_Load()
    716         {
    717             var unit = this.CreateConfigurationUnit();
    718             DscResourceInfoInternal? nullDscResourceInfo = null;
    719             var (dscResourceInfo, psModuleInfo) = this.GetResourceAndModuleInfo(unit);
    720             var getFindResourceInfo = this.CreateFindResourceInfo();
    721 
    722             var processorEnvMock = new Mock<IProcessorEnvironment>();
    723             processorEnvMock.SetupSequence(
    724                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)))
    725                 .Returns(nullDscResourceInfo)
    726                 .Returns(dscResourceInfo);
    727             processorEnvMock.Setup(
    728                 m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => unit.Type == unit.Type)))
    729                 .Returns(getFindResourceInfo)
    730                 .Verifiable();
    731             processorEnvMock.Setup(
    732                 m => m.InstallModule(getFindResourceInfo))
    733                 .Verifiable();
    734             processorEnvMock.Setup(
    735                 m => m.GetInstalledModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))
    736                 .Returns(getFindResourceInfo)
    737                 .Verifiable();
    738             processorEnvMock.Setup(
    739                 m => m.ImportModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))
    740                 .Verifiable();
    741 
    742             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    743                 processorEnvMock.Object,
    744                 new ConfigurationSet());
    745 
    746             var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(
    747                 unit,
    748                 ConfigurationUnitDetailFlags.Load);
    749 
    750             Assert.NotNull(configurationUnitProcessorDetails);
    751             Assert.Equal(dscResourceInfo.Name, configurationUnitProcessorDetails.UnitType);
    752 
    753             processorEnvMock.Verify();
    754             processorEnvMock.Verify(
    755                 m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)),
    756                 Times.Exactly(2));
    757         }
    758 
    759         /// <summary>
    760         /// This tests uses SimpleTestResourceTypes Test to validate the resource got the correct types
    761         /// from the processor.
    762         /// </summary>
    763         [Fact]
    764         public void CreateUnitProcessor_TestTypes()
    765         {
    766             var processorEnv = this.fixture.PrepareTestProcessorEnvironment();
    767 
    768             var setProcessor = new PowerShellConfigurationSetProcessor(processorEnv, new ConfigurationSet());
    769 
    770             var unit = new ConfigurationUnit
    771             {
    772                 Type = "SimpleTestResourceTypes",
    773                 Intent = ConfigurationUnitIntent.Assert,
    774             };
    775 
    776             unit.Metadata.Add("module", "xSimpleTestResource");
    777             unit.Metadata.Add("version", "0.0.0.1");
    778 
    779             var hashtableProperty = new ValueSet
    780             {
    781                 { "secretStringKey", "secretCode" },
    782                 { "secretIntKey", "123456" },
    783             };
    784 
    785             unit.Settings.Add("boolProperty", true);
    786             unit.Settings.Add("intProperty", 3);
    787             unit.Settings.Add("doubleProperty", -9.876);
    788             unit.Settings.Add("charProperty", 'f');
    789             unit.Settings.Add("hashtableProperty", hashtableProperty);
    790 
    791             var unitProcessor = setProcessor.CreateUnitProcessor(unit);
    792 
    793             unitProcessor.TestSettings();
    794         }
    795 
    796         /// <summary>
    797         /// Tests a module that requires admin is loaded from non admin.
    798         /// </summary>
    799         [FactSkipIfCI]
    800         public void CreateUnitProcessor_ModuleRequiresAdmin()
    801         {
    802             var processorEnv = this.fixture.PrepareTestProcessorEnvironment();
    803 
    804             var setProcessor = new PowerShellConfigurationSetProcessor(processorEnv, new ConfigurationSet());
    805 
    806             var unit = new ConfigurationUnit
    807             {
    808                 Type = "AdminResource",
    809                 Intent = ConfigurationUnitIntent.Assert,
    810             };
    811             unit.Metadata.Add("module", "xAdminTestResource");
    812             unit.Metadata.Add("version", "0.0.0.1");
    813 
    814             unit.Settings.Add("key", "key");
    815 
    816             var importModuleException = Assert.Throws<ImportModuleException>(() => setProcessor.CreateUnitProcessor(unit));
    817             Assert.Equal(ErrorCodes.WinGetConfigUnitImportModuleAdmin, importModuleException.HResult);
    818         }
    819 
    820         /// <summary>
    821         /// Test CreateUnitProcessor. Limit mode.
    822         /// </summary>
    823         [Fact]
    824         public void CreateUnitProcessor_LimitMode()
    825         {
    826             string resourceName = "xResourceName";
    827             string moduleName = "xModuleName";
    828             Version version = new Version("1.0");
    829 
    830             var processorEnvMock = new Mock<IProcessorEnvironment>();
    831             processorEnvMock.Setup(
    832                     m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    833                 .Returns(new DscResourceInfoInternal(resourceName, moduleName, version))
    834                 .Verifiable();
    835 
    836             var limitSet = new ConfigurationSet();
    837             var limitUnit = new ConfigurationUnit
    838             {
    839                 Type = resourceName,
    840                 Intent = ConfigurationUnitIntent.Apply,
    841             };
    842             limitUnit.Metadata.Add("module", moduleName);
    843             limitUnit.Metadata.Add("version", version.ToString());
    844             limitSet.Units = new List<ConfigurationUnit> { limitUnit };
    845 
    846             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    847                 processorEnvMock.Object,
    848                 limitSet,
    849                 true);
    850 
    851             // Calling with unit different from limit set should throw.
    852             var unitDifferentContent = new ConfigurationUnit
    853             {
    854                 Type = "differentResourceName",
    855                 Intent = ConfigurationUnitIntent.Apply,
    856             };
    857 
    858             Assert.Throws<System.InvalidOperationException>(() => configurationSetProcessor.CreateUnitProcessor(unitDifferentContent));
    859             Assert.Throws<System.InvalidOperationException>(() => configurationSetProcessor.GetUnitProcessorDetails(unitDifferentContent, ConfigurationUnitDetailFlags.Load));
    860 
    861             // Calling with unit matching limit set.
    862             var unitProcessor = configurationSetProcessor.CreateUnitProcessor(limitUnit);
    863             Assert.NotNull(unitProcessor);
    864             Assert.Equal(limitUnit.Type, unitProcessor.Unit.Type);
    865             var processorDetails = configurationSetProcessor.GetUnitProcessorDetails(limitUnit, ConfigurationUnitDetailFlags.Load);
    866             Assert.NotNull(processorDetails);
    867             Assert.Equal(moduleName, processorDetails.ModuleName);
    868 
    869             // Calling CreateProcessor again should thow. Calling GetProcessorDetails multiple times is ok.
    870             Assert.Throws<System.InvalidOperationException>(() => configurationSetProcessor.CreateUnitProcessor(limitUnit));
    871             var processorDetails2 = configurationSetProcessor.GetUnitProcessorDetails(limitUnit, ConfigurationUnitDetailFlags.Load);
    872             Assert.NotNull(processorDetails2);
    873             Assert.Equal(moduleName, processorDetails2.ModuleName);
    874         }
    875 
    876         /// <summary>
    877         /// Test CreateUnitProcessor. Limit mode. Duplicate units in limit set.
    878         /// </summary>
    879         [Fact]
    880         public void CreateUnitProcessor_LimitMode_DuplicateUnits()
    881         {
    882             string resourceName = "xResourceName";
    883             string moduleName = "xModuleName";
    884             Version version = new Version("1.0");
    885 
    886             var processorEnvMock = new Mock<IProcessorEnvironment>();
    887             processorEnvMock.Setup(
    888                     m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))
    889                 .Returns(new DscResourceInfoInternal(resourceName, moduleName, version))
    890                 .Verifiable();
    891 
    892             var limitSet = new ConfigurationSet();
    893             var limitUnit = new ConfigurationUnit
    894             {
    895                 Type = resourceName,
    896                 Intent = ConfigurationUnitIntent.Apply,
    897             };
    898             limitUnit.Metadata.Add("module", moduleName);
    899             limitUnit.Metadata.Add("version", version.ToString());
    900             limitSet.Units = new List<ConfigurationUnit> { limitUnit, limitUnit };
    901 
    902             var configurationSetProcessor = new PowerShellConfigurationSetProcessor(
    903                 processorEnvMock.Object,
    904                 limitSet,
    905                 true);
    906 
    907             // Calling with unit different from limit set should throw.
    908             var unitDifferentContent = new ConfigurationUnit
    909             {
    910                 Type = "differentResourceName",
    911                 Intent = ConfigurationUnitIntent.Apply,
    912             };
    913 
    914             Assert.Throws<System.InvalidOperationException>(() => configurationSetProcessor.CreateUnitProcessor(unitDifferentContent));
    915 
    916             // Calling with unit matching limit set.
    917             var unitProcessor = configurationSetProcessor.CreateUnitProcessor(limitUnit);
    918             Assert.NotNull(unitProcessor);
    919             Assert.Equal(limitUnit.Type, unitProcessor.Unit.Type);
    920 
    921             // Calling again should also not thow.
    922             var unitProcessor2 = configurationSetProcessor.CreateUnitProcessor(limitUnit);
    923             Assert.NotNull(unitProcessor2);
    924             Assert.Equal(limitUnit.Type, unitProcessor2.Unit.Type);
    925 
    926             // Calling third time should throw.
    927             Assert.Throws<System.InvalidOperationException>(() => configurationSetProcessor.CreateUnitProcessor(limitUnit));
    928         }
    929 
    930         private ConfigurationUnit CreateConfigurationUnit()
    931         {
    932             var unit = new ConfigurationUnit();
    933             unit.Type = "SimpleFileResource";
    934             unit.Metadata.Add("module", "xSimpleTestResource");
    935             unit.Metadata.Add("version", "0.0.0.1");
    936 
    937             return unit;
    938         }
    939 
    940         private (DscResourceInfoInternal dscResourceInfo, PSModuleInfo psModuleInfo) GetResourceAndModuleInfo(ConfigurationUnit unit)
    941         {
    942             // This is easier than trying to mock sealed class from external code...
    943             var testEnv = this.fixture.PrepareTestProcessorEnvironment(true);
    944             var dscResourceInfo = testEnv.GetDscResource(new ConfigurationUnitAndModule(unit, string.Empty));
    945             var psModuleInfo = testEnv.GetAvailableModule(PowerShellHelpers.CreateModuleSpecification("xSimpleTestResource", "0.0.0.1"));
    946 
    947             if (dscResourceInfo is null || psModuleInfo is null)
    948             {
    949                 throw new ArgumentNullException("Test processor environment not set correctly");
    950             }
    951 
    952             return (dscResourceInfo, psModuleInfo);
    953         }
    954 
    955         private PSObject CreateGetModuleInfo()
    956         {
    957             return new PSObject(new
    958             {
    959                 Repository = "PSGallery",
    960                 PublishedDate = new DateTime(2017, 12, 10),
    961                 IconUri = "https://github.com/microsoft/winget-cli",
    962                 Name = "xSimpleTestResource",
    963                 Description = "PowerShell module with DSC resources for unit tests",
    964                 RepositorySourceLocation = "https://github.com/microsoft/winget-cli",
    965                 Version = "0.0.0.1",
    966                 Author = "Luffytaro",
    967                 CompanyName = "Microsoft Corporation",
    968             });
    969         }
    970 
    971         private PSObject CreateFindResourceInfo()
    972         {
    973             var getModuleInfo = this.CreateGetModuleInfo();
    974             return new PSObject(new
    975             {
    976                 Name = "SimpleFileResource",
    977                 ModuleName = "xSimpleTestResource",
    978                 Version = "0.0.0.1",
    979                 PSGetModuleInfo = getModuleInfo,
    980             });
    981         }
    982     }
    983 }