winget-cli

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

ConfigurationHistoryTests.cs (16138B)


      1 // -----------------------------------------------------------------------------
      2 // <copyright file="ConfigurationHistoryTests.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.Diagnostics;
     12     using System.Diagnostics.CodeAnalysis;
     13     using System.Xml.Linq;
     14     using Microsoft.Management.Configuration.Processor.Extensions;
     15     using Microsoft.Management.Configuration.UnitTests.Fixtures;
     16     using Microsoft.Management.Configuration.UnitTests.Helpers;
     17     using Microsoft.VisualBasic;
     18     using Xunit;
     19     using Xunit.Abstractions;
     20 
     21     /// <summary>
     22     /// Unit tests for configuration history.
     23     /// </summary>
     24     [Collection("UnitTestCollection")]
     25     [InProc]
     26     public class ConfigurationHistoryTests : ConfigurationProcessorTestBase
     27     {
     28         /// <summary>
     29         /// Initializes a new instance of the <see cref="ConfigurationHistoryTests"/> class.
     30         /// </summary>
     31         /// <param name="fixture">Unit test fixture.</param>
     32         /// <param name="log">Log helper.</param>
     33         public ConfigurationHistoryTests(UnitTestFixture fixture, ITestOutputHelper log)
     34             : base(fixture, log)
     35         {
     36         }
     37 
     38         /// <summary>
     39         /// Checks that the history matches the applied set.
     40         /// </summary>
     41         [Fact]
     42         [OutOfProc]
     43         public void ApplySet_HistoryMatches_0_1()
     44         {
     45             this.RunApplyHistoryMatchTest(
     46                 @"
     47 properties:
     48   configurationVersion: 0.1
     49   assertions:
     50     - resource: Assert
     51       id: AssertIdentifier1
     52       directives:
     53         module: Module
     54       settings:
     55         Setting1: '1'
     56         Setting2: 2
     57     - resource: Assert
     58       id: AssertIdentifier2
     59       dependsOn:
     60         - AssertIdentifier1
     61       directives:
     62         module: Module
     63       settings:
     64         Setting1:
     65           Setting2: 2
     66   parameters:
     67     - resource: Inform
     68       id: InformIdentifier1
     69       directives:
     70         module: Module2
     71       settings:
     72         Setting1:
     73           Setting2:
     74             Setting3: 3
     75   resources:
     76     - resource: Apply
     77 ", new string[] { "AssertIdentifier2" });
     78         }
     79 
     80         /// <summary>
     81         /// Checks that the history matches the applied set.
     82         /// </summary>
     83         [Fact]
     84         [OutOfProc]
     85         public void ApplySet_HistoryMatches_0_2()
     86         {
     87             this.RunApplyHistoryMatchTest(
     88                 @"
     89 properties:
     90   configurationVersion: 0.2
     91   assertions:
     92     - resource: Module/Assert
     93       id: AssertIdentifier1
     94       settings:
     95         Setting1: '1'
     96         Setting2: 2
     97     - resource: Module/Assert
     98       id: AssertIdentifier2
     99       dependsOn:
    100         - AssertIdentifier1
    101       directives:
    102         description: Describe!
    103       settings:
    104         Setting1:
    105           Setting2: 2
    106   parameters:
    107     - resource: Module2/Inform
    108       id: InformIdentifier1
    109       settings:
    110         Setting1:
    111           Setting2:
    112             Setting3: 3
    113   resources:
    114     - resource: Apply
    115 ", new string[] { "AssertIdentifier2" });
    116         }
    117 
    118         /// <summary>
    119         /// Checks that the history matches the applied set.
    120         /// </summary>
    121         [Fact]
    122         public void ApplySet_HistoryMatches_0_3()
    123         {
    124             this.RunApplyHistoryMatchTest(
    125                 @"
    126 $schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
    127 metadata:
    128   a: 1
    129   b: '2'
    130 variables:
    131   v1: var1
    132   v2: 42
    133 resources:
    134   - name: Name
    135     type: Module/Resource
    136     metadata:
    137       e: '5'
    138       f: 6
    139     properties:
    140       c: 3
    141       d: '4'
    142   - name: Name2
    143     type: Module/Resource2
    144     dependsOn:
    145       - Name
    146     properties:
    147       l: '10'
    148     metadata:
    149       i: '7'
    150       j: 8
    151       q: 42
    152   - name: Group
    153     type: Module2/Resource
    154     metadata:
    155       isGroup: true
    156     properties:
    157       resources:
    158         - name: Child1
    159           type: Module3/Resource
    160           metadata:
    161             e: '5'
    162             f: 6
    163           properties:
    164             c: 3
    165             d: '4'
    166         - name: Child2
    167           type: Module4/Resource2
    168           properties:
    169             l: '10'
    170           metadata:
    171             i: '7'
    172             j: 8
    173             q: 42
    174 ");
    175         }
    176 
    177         /// <summary>
    178         /// Applies a set, reads the history, changes the read set and reapplies it.
    179         /// </summary>
    180         [Fact]
    181         [OutOfProc]
    182         public void ApplySet_ChangeHistory()
    183         {
    184             string disabledIdentifier = "AssertIdentifier2";
    185 
    186             ConfigurationSet returnedSet = this.RunApplyHistoryMatchTest(
    187                 @"
    188 properties:
    189   configurationVersion: 0.2
    190   assertions:
    191     - resource: Module/Assert
    192       id: AssertIdentifier1
    193       settings:
    194         Setting1: '1'
    195         Setting2: 2
    196     - resource: Module/Assert
    197       id: AssertIdentifier2
    198       dependsOn:
    199         - AssertIdentifier1
    200       directives:
    201         description: Describe!
    202       settings:
    203         Setting1:
    204           Setting2: 2
    205   parameters:
    206     - resource: Module2/Inform
    207       id: InformIdentifier1
    208       settings:
    209         Setting1:
    210           Setting2:
    211             Setting3: 3
    212   resources:
    213     - resource: Apply
    214 ", new string[] { disabledIdentifier });
    215 
    216             foreach (ConfigurationUnit unit in returnedSet.Units)
    217             {
    218                 if (unit.Identifier == disabledIdentifier)
    219                 {
    220                     unit.IsActive = true;
    221                 }
    222             }
    223 
    224             TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();
    225             ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);
    226 
    227             ApplyConfigurationSetResult result = processor.ApplySet(returnedSet, ApplyConfigurationSetFlags.None);
    228             Assert.NotNull(result);
    229             Assert.Null(result.ResultCode);
    230 
    231             ConfigurationSet? historySet = null;
    232 
    233             foreach (ConfigurationSet set in processor.GetConfigurationHistory())
    234             {
    235                 if (set.InstanceIdentifier == returnedSet.InstanceIdentifier)
    236                 {
    237                     historySet = set;
    238                 }
    239             }
    240 
    241             this.AssertSetsEqual(returnedSet, historySet);
    242         }
    243 
    244         /// <summary>
    245         /// Applies a set, reads the history and removes it.
    246         /// </summary>
    247         [Fact]
    248         [OutOfProc]
    249         public void ApplySet_RemoveHistory()
    250         {
    251             ConfigurationSet returnedSet = this.RunApplyHistoryMatchTest(
    252                 @"
    253 properties:
    254   configurationVersion: 0.2
    255   assertions:
    256     - resource: Module/Assert
    257       id: AssertIdentifier1
    258       settings:
    259         Setting1: '1'
    260         Setting2: 2
    261     - resource: Module/Assert
    262       id: AssertIdentifier2
    263       dependsOn:
    264         - AssertIdentifier1
    265       directives:
    266         description: Describe!
    267       settings:
    268         Setting1:
    269           Setting2: 2
    270   parameters:
    271     - resource: Module2/Inform
    272       id: InformIdentifier1
    273       settings:
    274         Setting1:
    275           Setting2:
    276             Setting3: 3
    277   resources:
    278     - resource: Apply
    279 ");
    280 
    281             returnedSet.Remove();
    282 
    283             TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();
    284             ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);
    285 
    286             ConfigurationSet? historySet = null;
    287 
    288             foreach (ConfigurationSet set in processor.GetConfigurationHistory())
    289             {
    290                 if (set.InstanceIdentifier == returnedSet.InstanceIdentifier)
    291                 {
    292                     historySet = set;
    293                 }
    294             }
    295 
    296             Assert.Null(historySet);
    297         }
    298 
    299         [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1011:Closing square brackets should be spaced correctly", Justification = "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2927")]
    300         private ConfigurationSet RunApplyHistoryMatchTest(string contents, string[]? inactiveIdentifiers = null)
    301         {
    302             TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();
    303             ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);
    304 
    305             OpenConfigurationSetResult configurationSetResult = processor.OpenConfigurationSet(this.CreateStream(contents));
    306             ConfigurationSet configurationSet = configurationSetResult.Set;
    307             Assert.NotNull(configurationSet);
    308 
    309             TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);
    310             setProcessor.EnableDefaultGroupProcessorCreation = true;
    311 
    312             configurationSet.Name = "Test Name";
    313             configurationSet.Origin = "Test Origin";
    314             configurationSet.Path = "Test Path";
    315 
    316             if (inactiveIdentifiers != null)
    317             {
    318                 foreach (string identifier in inactiveIdentifiers)
    319                 {
    320                     foreach (ConfigurationUnit unit in configurationSet.Units)
    321                     {
    322                         if (unit.Identifier == identifier)
    323                         {
    324                             unit.IsActive = false;
    325                         }
    326                     }
    327                 }
    328             }
    329 
    330             ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);
    331             Assert.NotNull(result);
    332             Assert.Null(result.ResultCode);
    333 
    334             ConfigurationSet? historySet = null;
    335 
    336             foreach (ConfigurationSet set in processor.GetConfigurationHistory())
    337             {
    338                 if (set.InstanceIdentifier == configurationSet.InstanceIdentifier)
    339                 {
    340                     historySet = set;
    341                 }
    342             }
    343 
    344             this.AssertSetsEqual(configurationSet, historySet);
    345             this.AssertResultsEqual(result, historySet);
    346             return historySet;
    347         }
    348 
    349         private void AssertSetsEqual(ConfigurationSet expectedSet, [NotNull] ConfigurationSet? actualSet)
    350         {
    351             Assert.NotNull(actualSet);
    352             Assert.Equal(expectedSet.Name, actualSet.Name);
    353             Assert.Equal(expectedSet.Origin, actualSet.Origin);
    354             Assert.Equal(expectedSet.Path, actualSet.Path);
    355 
    356             Assert.Equal(ConfigurationSetState.Completed, actualSet.State);
    357 
    358             this.AssertTimeNotZero(actualSet.FirstApply);
    359             this.AssertTimeNotZero(actualSet.ApplyBegun);
    360             this.AssertTimeNotZero(actualSet.ApplyEnded);
    361             Assert.True(actualSet.FirstApply <= actualSet.ApplyBegun);
    362             Assert.True(actualSet.ApplyBegun <= actualSet.ApplyEnded);
    363 
    364             Assert.Equal(expectedSet.SchemaVersion, actualSet.SchemaVersion);
    365             Assert.Equal(expectedSet.SchemaUri, actualSet.SchemaUri);
    366             Assert.True(expectedSet.Metadata.ContentEquals(actualSet.Metadata));
    367 
    368             this.AssertUnitsListEqual(expectedSet.Units, actualSet.Units);
    369         }
    370 
    371         private void AssertTimeNotZero(DateTimeOffset actualTime)
    372         {
    373             Assert.NotEqual(DateTimeOffset.UnixEpoch, actualTime);
    374             Assert.NotEqual(DateTimeOffset.MinValue, actualTime);
    375         }
    376 
    377         private void AssertUnitsListEqual(IList<ConfigurationUnit> expectedUnits, IList<ConfigurationUnit> actualUnits)
    378         {
    379             Assert.Equal(expectedUnits.Count, actualUnits.Count);
    380 
    381             foreach (ConfigurationUnit expectedUnit in expectedUnits)
    382             {
    383                 ConfigurationUnit? actualUnit = null;
    384                 foreach (ConfigurationUnit historyUnit in actualUnits)
    385                 {
    386                     if (historyUnit.InstanceIdentifier == expectedUnit.InstanceIdentifier)
    387                     {
    388                         actualUnit = historyUnit;
    389                     }
    390                 }
    391 
    392                 this.AssertUnitsEqual(expectedUnit, actualUnit);
    393             }
    394         }
    395 
    396         private void AssertUnitsEqual(ConfigurationUnit expectedUnit, ConfigurationUnit? actualUnit)
    397         {
    398             Assert.NotNull(actualUnit);
    399             Assert.Equal(expectedUnit.Type, actualUnit.Type);
    400             Assert.Equal(expectedUnit.Identifier, actualUnit.Identifier);
    401             Assert.Equal(expectedUnit.Intent, actualUnit.Intent);
    402             Assert.Equal(expectedUnit.Dependencies, actualUnit.Dependencies);
    403             Assert.True(expectedUnit.Metadata.ContentEquals(actualUnit.Metadata), $"Metadata not equal: {expectedUnit.Identifier}\n---expected---:\n{expectedUnit.Metadata.ToYaml()}\n---actual---:\n{actualUnit.Metadata.ToYaml()}");
    404             Assert.True(expectedUnit.Settings.ContentEquals(actualUnit.Settings));
    405             Assert.Equal(expectedUnit.IsActive, actualUnit.IsActive);
    406             Assert.Equal(expectedUnit.IsGroup, actualUnit.IsGroup);
    407 
    408             if (expectedUnit.IsGroup)
    409             {
    410                 this.AssertUnitsListEqual(expectedUnit.Units, actualUnit.Units);
    411             }
    412         }
    413 
    414         private void AssertResultsEqual(ApplyConfigurationSetResult expected, ConfigurationSet actualSet)
    415         {
    416             List<ConfigurationUnit> actualUnitList = new List<ConfigurationUnit>();
    417 
    418             foreach (ConfigurationUnit unit in actualSet.Units)
    419             {
    420                 this.AccumulateUnits(actualUnitList, unit);
    421             }
    422 
    423             foreach (ApplyConfigurationUnitResult expectedUnitResult in expected.UnitResults)
    424             {
    425                 ConfigurationUnit? actualUnit = null;
    426                 foreach (ConfigurationUnit historyUnit in actualUnitList)
    427                 {
    428                     if (historyUnit.InstanceIdentifier == expectedUnitResult.Unit.InstanceIdentifier)
    429                     {
    430                         actualUnit = historyUnit;
    431                     }
    432                 }
    433 
    434                 this.AssertUnitResultsEqual(expectedUnitResult, actualUnit);
    435             }
    436         }
    437 
    438         private void AccumulateUnits(List<ConfigurationUnit> unitList, ConfigurationUnit unit)
    439         {
    440             unitList.Add(unit);
    441             if (unit.IsGroup)
    442             {
    443                 foreach (ConfigurationUnit child in unit.Units)
    444                 {
    445                     this.AccumulateUnits(unitList, child);
    446                 }
    447             }
    448         }
    449 
    450         private void AssertUnitResultsEqual(ApplyConfigurationUnitResult expectedResult, ConfigurationUnit? actualUnit)
    451         {
    452             Assert.NotNull(actualUnit);
    453             Assert.Equal(expectedResult.State, actualUnit.State);
    454 
    455             var expectedResultInformation = expectedResult.ResultInformation;
    456             if (expectedResultInformation != null)
    457             {
    458                 var actualResultInformation = actualUnit.ResultInformation;
    459                 Assert.NotNull(actualResultInformation);
    460 
    461                 Assert.Equal(expectedResultInformation.ResultCode == null, actualResultInformation.ResultCode == null);
    462                 if (expectedResultInformation.ResultCode != null)
    463                 {
    464                     Assert.Equal(expectedResultInformation.ResultCode.HResult, actualResultInformation.ResultCode!.HResult);
    465                 }
    466 
    467                 Assert.Equal(expectedResultInformation.Description, actualResultInformation.Description);
    468                 Assert.Equal(expectedResultInformation.Details, actualResultInformation.Details);
    469                 Assert.Equal(expectedResultInformation.ResultSource, actualResultInformation.ResultSource);
    470             }
    471         }
    472     }
    473 }