winget-cli

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

ConfigurationMixedElevationTests.cs (15553B)


      1 // -----------------------------------------------------------------------------
      2 // <copyright file="ConfigurationMixedElevationTests.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.IO;
     11     using System.Threading.Tasks;
     12     using Microsoft.Management.Configuration.UnitTests.Fixtures;
     13     using Microsoft.Management.Configuration.UnitTests.Helpers;
     14     using Xunit;
     15     using Xunit.Abstractions;
     16 
     17     /// <summary>
     18     /// Unit tests for verifying the processor behavior for handling mixed elevation scenarios.
     19     /// </summary>
     20     [Collection("UnitTestCollection")]
     21     [OutOfProc]
     22     public class ConfigurationMixedElevationTests : ConfigurationProcessorTestBase
     23     {
     24         private readonly UnitTestFixture fixture;
     25         private readonly ITestOutputHelper log;
     26 
     27         /// <summary>
     28         /// Initializes a new instance of the <see cref="ConfigurationMixedElevationTests"/> class.
     29         /// </summary>
     30         /// <param name="fixture">Unit test fixture.</param>
     31         /// <param name="log">Log helper.</param>
     32         public ConfigurationMixedElevationTests(UnitTestFixture fixture, ITestOutputHelper log)
     33             : base(fixture, log)
     34         {
     35             this.fixture = fixture;
     36             this.log = log;
     37         }
     38 
     39         /// <summary>
     40         /// Verifies that applying units of mixed elevation is successful. Also verifies that the elevated processor has a different process id.
     41         /// </summary>
     42         /// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
     43         [Fact]
     44         public async Task ApplyMixedElevationUnits()
     45         {
     46             string resourceName = "E2ETestResourcePID";
     47             string moduleName = "xE2ETestResource";
     48             Version version = new Version("0.0.0.1");
     49 
     50             string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
     51             Directory.CreateDirectory(tempDirectory);
     52 
     53             ConfigurationSet configurationSet = this.ConfigurationSet();
     54             configurationSet.SchemaVersion = "0.2";
     55             configurationSet.Metadata.Add(Helpers.Constants.EnableDynamicFactoryTestMode, true);
     56 
     57             ConfigurationUnit unit = this.ConfigurationUnit();
     58             unit.Metadata.Add("version", version.ToString());
     59             unit.Metadata.Add("module", moduleName);
     60             unit.Settings.Add("directoryPath", tempDirectory);
     61             unit.Type = resourceName;
     62             unit.Intent = ConfigurationUnitIntent.Apply;
     63 
     64             ConfigurationUnit elevatedUnit = this.ConfigurationUnit();
     65             elevatedUnit.Metadata.Add("version", version.ToString());
     66             elevatedUnit.Metadata.Add("module", moduleName);
     67             elevatedUnit.Environment.Context = SecurityContext.Elevated;
     68             elevatedUnit.Settings.Add("directoryPath", tempDirectory);
     69             elevatedUnit.Type = resourceName;
     70             elevatedUnit.Intent = ConfigurationUnitIntent.Apply;
     71 
     72             configurationSet.Units = new ConfigurationUnit[] { unit, elevatedUnit };
     73 
     74             IConfigurationSetProcessorFactory dynamicFactory = await this.fixture.ConfigurationStatics.CreateConfigurationSetProcessorFactoryAsync(Helpers.Constants.DynamicRuntimeHandlerIdentifier);
     75 
     76             ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(dynamicFactory);
     77 
     78             ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);
     79 
     80             // Get the number of unique PIDs from temp directory.
     81             int pidCount = Directory.GetFiles(tempDirectory).Length;
     82 
     83             // Clean up temp directory folder.
     84             Directory.Delete(tempDirectory, true);
     85 
     86             Assert.NotNull(result);
     87             Assert.Null(result.ResultCode);
     88             Assert.Equal(2, result.UnitResults.Count);
     89 
     90             foreach (var unitResult in result.UnitResults)
     91             {
     92                 Assert.NotNull(unitResult);
     93                 Assert.False(unitResult.PreviouslyInDesiredState);
     94                 Assert.False(unitResult.RebootRequired);
     95                 Assert.NotNull(unitResult.ResultInformation);
     96                 Assert.Null(unitResult.ResultInformation.ResultCode);
     97                 Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);
     98             }
     99 
    100             // There should be exactly 2 unique PIDs, one for each integrity level.
    101             Assert.Equal(2, pidCount);
    102         }
    103 
    104         /// <summary>
    105         /// Verifies that applying units of mixed elevation is successful. Also verifies that the elevated processor has a different process id.
    106         /// </summary>
    107         /// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
    108         [Fact]
    109         public async Task ApplyMixedElevationUnits_Schema_0_3()
    110         {
    111             string resourceName = "xE2ETestResource/E2ETestResourcePID";
    112             Version version = new Version("0.0.0.1");
    113 
    114             string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
    115             Directory.CreateDirectory(tempDirectory);
    116 
    117             ConfigurationSet configurationSet = this.ConfigurationSet();
    118             configurationSet.SchemaVersion = "0.3";
    119             configurationSet.Metadata.Add(Helpers.Constants.EnableDynamicFactoryTestMode, true);
    120 
    121             ConfigurationUnit unit = this.ConfigurationUnit();
    122             unit.Metadata.Add("version", version.ToString());
    123             unit.Settings.Add("directoryPath", tempDirectory);
    124             unit.Type = resourceName;
    125             unit.Identifier = "current";
    126 
    127             ConfigurationUnit elevatedUnit = this.ConfigurationUnit();
    128             elevatedUnit.Intent = ConfigurationUnitIntent.Unknown;
    129             elevatedUnit.Metadata.Add("version", version.ToString());
    130             elevatedUnit.Environment.Context = SecurityContext.Elevated;
    131             elevatedUnit.Settings.Add("directoryPath", tempDirectory);
    132             elevatedUnit.Type = resourceName;
    133             elevatedUnit.Identifier = "elevated";
    134 
    135             configurationSet.Units = new ConfigurationUnit[] { unit, elevatedUnit };
    136 
    137             IConfigurationSetProcessorFactory dynamicFactory = await this.fixture.ConfigurationStatics.CreateConfigurationSetProcessorFactoryAsync(Helpers.Constants.DynamicRuntimeHandlerIdentifier);
    138 
    139             ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(dynamicFactory);
    140 
    141             ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);
    142 
    143             // Get the number of unique PIDs from temp directory.
    144             int pidCount = Directory.GetFiles(tempDirectory).Length;
    145 
    146             // Clean up temp directory folder.
    147             Directory.Delete(tempDirectory, true);
    148 
    149             Assert.NotNull(result);
    150             Assert.Null(result.ResultCode);
    151             Assert.Equal(2, result.UnitResults.Count);
    152 
    153             foreach (var unitResult in result.UnitResults)
    154             {
    155                 Assert.NotNull(unitResult);
    156                 Assert.False(unitResult.PreviouslyInDesiredState);
    157                 Assert.False(unitResult.RebootRequired);
    158                 Assert.NotNull(unitResult.ResultInformation);
    159                 Assert.Null(unitResult.ResultInformation.ResultCode);
    160                 Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);
    161             }
    162 
    163             // There should be exactly 2 unique PIDs, one for each integrity level.
    164             Assert.Equal(2, pidCount);
    165         }
    166 
    167         /// <summary>
    168         /// Verifies that creating a high integrity unit processor for a non elevated unit should return an invalid operation result.
    169         /// </summary>
    170         /// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
    171         [Fact]
    172         public async Task ApplyUnitNotInLimitationSet()
    173         {
    174             string resourceName = "E2ETestResource";
    175             string moduleName = "xE2ETestResource";
    176             Version version = new Version("0.0.0.1");
    177 
    178             ConfigurationSet configurationSet = this.ConfigurationSet();
    179             configurationSet.SchemaVersion = "0.2";
    180             configurationSet.Metadata.Add(Helpers.Constants.EnableDynamicFactoryTestMode, true);
    181             configurationSet.Metadata.Add(Helpers.Constants.ForceHighIntegrityLevelUnitsTestGuid, true);
    182             configurationSet.Metadata.Add(Helpers.Constants.EnableRestrictedIntegrityLevelTestGuid, true);
    183 
    184             ConfigurationUnit unit = this.ConfigurationUnit();
    185             unit.Metadata.Add("version", version.ToString());
    186             unit.Metadata.Add("module", moduleName);
    187             unit.Metadata.Add("unique", "value");
    188             unit.Type = resourceName;
    189             unit.Intent = ConfigurationUnitIntent.Apply;
    190 
    191             ConfigurationUnit elevatedUnit = this.ConfigurationUnit();
    192             elevatedUnit.Metadata.Add("version", version.ToString());
    193             elevatedUnit.Metadata.Add("module", moduleName);
    194             elevatedUnit.Environment.Context = SecurityContext.Elevated;
    195             elevatedUnit.Type = resourceName;
    196             elevatedUnit.Intent = ConfigurationUnitIntent.Apply;
    197 
    198             configurationSet.Units = new ConfigurationUnit[] { unit, elevatedUnit };
    199 
    200             IConfigurationSetProcessorFactory dynamicFactory = await this.fixture.ConfigurationStatics.CreateConfigurationSetProcessorFactoryAsync(Helpers.Constants.DynamicRuntimeHandlerIdentifier);
    201 
    202             ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(dynamicFactory);
    203 
    204             ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);
    205             Assert.NotNull(result);
    206             Assert.NotNull(result.ResultCode);
    207             Assert.Equal(Errors.WINGET_CONFIG_ERROR_SET_APPLY_FAILED, result.ResultCode.HResult);
    208             Assert.Equal(2, result.UnitResults.Count);
    209 
    210             ApplyConfigurationUnitResult unitResult = result.UnitResults[0];
    211             Assert.NotNull(unitResult);
    212             Assert.False(unitResult.PreviouslyInDesiredState);
    213             Assert.False(unitResult.RebootRequired);
    214             Assert.NotNull(unitResult.ResultInformation);
    215             Assert.NotNull(unitResult.ResultInformation.ResultCode);
    216             Assert.Equal(Errors.CORE_INVALID_OPERATION, unitResult.ResultInformation.ResultCode.HResult);
    217             Assert.Equal(ConfigurationUnitResultSource.Internal, unitResult.ResultInformation.ResultSource);
    218 
    219             // Elevated unit should still succeed when applied.
    220             ApplyConfigurationUnitResult elevatedUnitResult = result.UnitResults[1];
    221             Assert.NotNull(elevatedUnitResult);
    222             Assert.False(elevatedUnitResult.PreviouslyInDesiredState);
    223             Assert.False(elevatedUnitResult.RebootRequired);
    224             Assert.NotNull(elevatedUnitResult.ResultInformation);
    225             Assert.Null(elevatedUnitResult.ResultInformation.ResultCode);
    226             Assert.Equal(ConfigurationUnitResultSource.None, elevatedUnitResult.ResultInformation.ResultSource);
    227         }
    228 
    229         /// <summary>
    230         /// Verifies that attempting to pass a secure parameter across the integrity boundary fails.
    231         /// </summary>
    232         /// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
    233         [Fact]
    234         public async Task SecureParameterAcrossIntegrityBoundaryFails()
    235         {
    236             string resourceName = "E2ETestResourcePID";
    237             string moduleName = "xE2ETestResource";
    238             Version version = new Version("0.0.0.1");
    239 
    240             string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
    241             Directory.CreateDirectory(tempDirectory);
    242 
    243             ConfigurationSet configurationSet = this.ConfigurationSet();
    244             configurationSet.Metadata.Add(Helpers.Constants.EnableDynamicFactoryTestMode, true);
    245 
    246             ConfigurationUnit elevatedUnit = this.ConfigurationUnit();
    247             elevatedUnit.Metadata.Add("version", version.ToString());
    248             elevatedUnit.Metadata.Add("module", moduleName);
    249             elevatedUnit.Environment.Context = SecurityContext.Elevated;
    250             elevatedUnit.Settings.Add("directoryPath", tempDirectory);
    251             elevatedUnit.Type = resourceName;
    252             elevatedUnit.Intent = ConfigurationUnitIntent.Apply;
    253 
    254             configurationSet.Units = new ConfigurationUnit[] { elevatedUnit };
    255 
    256             ConfigurationParameter parameter = this.ConfigurationParameter();
    257             parameter.Name = "param";
    258             parameter.Type = Windows.Foundation.PropertyType.String;
    259             parameter.IsSecure = true;
    260             parameter.ProvidedValue = "secrets";
    261 
    262             configurationSet.Parameters = new ConfigurationParameter[] { parameter };
    263 
    264             IConfigurationSetProcessorFactory dynamicFactory = await this.fixture.ConfigurationStatics.CreateConfigurationSetProcessorFactoryAsync(Helpers.Constants.DynamicRuntimeHandlerIdentifier);
    265 
    266             ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(dynamicFactory);
    267 
    268             // While parameters are not supported, we expect to get a not implemented exception.
    269             // Once they are implemented, swap to the appropriate error mechanism for the parameter integrity boundary.
    270             Assert.Throws<NotImplementedException>(() => processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None));
    271         }
    272 
    273         /// <summary>
    274         /// Verifies that DynamicFactoryProcessors do not break on empty set when working with only units.
    275         /// </summary>
    276         /// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
    277         [Fact]
    278         public async Task CreateDynamicFactoryProcessorsWithEmptyConfigurationSet()
    279         {
    280             string resourceName = "E2ETestResourcePID";
    281             string moduleName = "xE2ETestResource";
    282             Version version = new Version("0.0.0.1");
    283 
    284             string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
    285             Directory.CreateDirectory(tempDirectory);
    286 
    287             ConfigurationUnit unit = this.ConfigurationUnit();
    288             unit.Metadata.Add("version", version.ToString());
    289             unit.Metadata.Add("module", moduleName);
    290             unit.Settings.Add("directoryPath", tempDirectory);
    291             unit.Type = resourceName;
    292             unit.Intent = ConfigurationUnitIntent.Inform;
    293 
    294             IConfigurationSetProcessorFactory dynamicFactory = await this.fixture.ConfigurationStatics.CreateConfigurationSetProcessorFactoryAsync(Helpers.Constants.DynamicRuntimeHandlerIdentifier);
    295 
    296             ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(dynamicFactory);
    297 
    298             var result = await processor.GetUnitSettingsAsync(unit);
    299 
    300             Assert.NotNull(result);
    301         }
    302     }
    303 }