ConfigurationUnitProcessorTests.cs (17450B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="ConfigurationUnitProcessorTests.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.Management.Automation; 11 using Microsoft.Management.Configuration; 12 using Microsoft.Management.Configuration.Processor.Helpers; 13 using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo; 14 using Microsoft.Management.Configuration.Processor.PowerShell.Helpers; 15 using Microsoft.Management.Configuration.Processor.PowerShell.ProcessorEnvironments; 16 using Microsoft.Management.Configuration.Processor.PowerShell.Unit; 17 using Microsoft.Management.Configuration.UnitTests.Fixtures; 18 using Microsoft.Management.Configuration.UnitTests.Helpers; 19 using Microsoft.PowerShell.Commands; 20 using Moq; 21 using Windows.Foundation.Collections; 22 using Xunit; 23 using Xunit.Abstractions; 24 25 /// <summary> 26 /// Configuration unit processor tests. 27 /// </summary> 28 [Collection("UnitTestCollection")] 29 [InProc] 30 public class ConfigurationUnitProcessorTests 31 { 32 private readonly UnitTestFixture fixture; 33 private readonly ITestOutputHelper log; 34 35 /// <summary> 36 /// Initializes a new instance of the <see cref="ConfigurationUnitProcessorTests"/> class. 37 /// </summary> 38 /// <param name="fixture">Unit test fixture.</param> 39 /// <param name="log">Log helper.</param> 40 public ConfigurationUnitProcessorTests(UnitTestFixture fixture, ITestOutputHelper log) 41 { 42 this.fixture = fixture; 43 this.log = log; 44 } 45 46 /// <summary> 47 /// Call GetSettings with all intents should succeed. 48 /// </summary> 49 /// <param name="intent">Intent.</param> 50 [Theory] 51 [InlineData(ConfigurationUnitIntent.Inform)] 52 [InlineData(ConfigurationUnitIntent.Assert)] 53 [InlineData(ConfigurationUnitIntent.Apply)] 54 public void GetSettings_Test(object intent) 55 { 56 string theKey = "key"; 57 string theValue = "value"; 58 var valueGetResult = new ValueSet 59 { 60 { theKey, theValue }, 61 }; 62 63 var processorEnvMock = new Mock<IProcessorEnvironment>(); 64 processorEnvMock.Setup(m => m.InvokeGetResource( 65 It.IsAny<ValueSet>(), 66 It.IsAny<string>(), 67 It.IsAny<ModuleSpecification?>())) 68 .Returns(valueGetResult) 69 .Verifiable(); 70 71 var unitResource = this.CreateUnitResource(Assert.IsType<ConfigurationUnitIntent>(intent)); 72 73 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource); 74 75 var result = unitProcessor.GetSettings(); 76 77 processorEnvMock.Verify(); 78 79 Assert.True(result.Settings.Count == 1); 80 Assert.True(result.Settings.ContainsKey(theKey)); 81 Assert.True(result.Settings.TryGetValue(theKey, out object keyValue)); 82 Assert.Equal(theValue, keyValue as string); 83 } 84 85 /// <summary> 86 /// Tests GetSettings when a System.Management.Automation.RuntimeException is thrown. 87 /// </summary> 88 [Fact] 89 public void GetSettings_Throws_Pwsh_RuntimeException() 90 { 91 var thrownException = new RuntimeException("a message"); 92 var processorEnvMock = new Mock<IProcessorEnvironment>(); 93 processorEnvMock.Setup(m => m.InvokeGetResource( 94 It.IsAny<ValueSet>(), 95 It.IsAny<string>(), 96 It.IsAny<ModuleSpecification?>())) 97 .Throws(() => thrownException) 98 .Verifiable(); 99 100 var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Inform); 101 102 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource); 103 104 var result = unitProcessor.GetSettings(); 105 106 processorEnvMock.Verify(); 107 108 // Do not check for the type. 109 Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult); 110 Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description)); 111 Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource); 112 } 113 114 /// <summary> 115 /// Tests GetSettings when a Microsoft.PowerShell.Commands.WriteErrorException is thrown. 116 /// </summary> 117 [Fact] 118 public void GetSettings_Throws_Pwsh_WriteErrorException() 119 { 120 var thrownException = new WriteErrorException("a message"); 121 var processorEnvMock = new Mock<IProcessorEnvironment>(); 122 processorEnvMock.Setup(m => m.InvokeGetResource( 123 It.IsAny<ValueSet>(), 124 It.IsAny<string>(), 125 It.IsAny<ModuleSpecification?>())) 126 .Throws(() => thrownException) 127 .Verifiable(); 128 129 var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Inform); 130 131 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource); 132 133 var result = unitProcessor.GetSettings(); 134 135 processorEnvMock.Verify(); 136 137 // Do not check for the type. 138 Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult); 139 Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description)); 140 Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource); 141 } 142 143 /// <summary> 144 /// Call TestSettings with Inform intent is not allowed. 145 /// </summary> 146 [Fact] 147 public void TestSettings_InformIntent() 148 { 149 var processorEnvMock = new Mock<IProcessorEnvironment>(); 150 var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Inform); 151 152 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource); 153 154 Assert.Throws<NotSupportedException>(() => unitProcessor.TestSettings()); 155 } 156 157 /// <summary> 158 /// Call TestSettings with Assert and Apply should work. 159 /// </summary> 160 /// <param name="intent">Intent.</param> 161 /// <param name="invokeTestResult">Invoke test result.</param> 162 [Theory] 163 [InlineData(ConfigurationUnitIntent.Assert, false)] 164 [InlineData(ConfigurationUnitIntent.Apply, false)] 165 [InlineData(ConfigurationUnitIntent.Assert, true)] 166 [InlineData(ConfigurationUnitIntent.Apply, true)] 167 public void TestSettings_TestSucceeded(object intent, bool invokeTestResult) 168 { 169 var processorEnvMock = new Mock<IProcessorEnvironment>(); 170 processorEnvMock.Setup(m => m.InvokeTestResource( 171 It.IsAny<ValueSet>(), 172 It.IsAny<string>(), 173 It.IsAny<ModuleSpecification?>())) 174 .Returns(invokeTestResult) 175 .Verifiable(); 176 177 var unitResource = this.CreateUnitResource(Assert.IsType<ConfigurationUnitIntent>(intent)); 178 179 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource); 180 181 var testResult = unitProcessor.TestSettings(); 182 183 processorEnvMock.Verify(); 184 185 var expectedConfigTestResult = ConfigurationTestResult.Negative; 186 if (invokeTestResult) 187 { 188 expectedConfigTestResult = ConfigurationTestResult.Positive; 189 } 190 191 Assert.Equal(expectedConfigTestResult, testResult.TestResult); 192 } 193 194 /// <summary> 195 /// Tests TestSettings when a System.Management.Automation.RuntimeException is thrown. 196 /// </summary> 197 [Fact] 198 public void TestSettings_Throws_Pwsh_RuntimeException() 199 { 200 var thrownException = new RuntimeException("a message"); 201 var processorEnvMock = new Mock<IProcessorEnvironment>(); 202 processorEnvMock.Setup(m => m.InvokeTestResource( 203 It.IsAny<ValueSet>(), 204 It.IsAny<string>(), 205 It.IsAny<ModuleSpecification?>())) 206 .Throws(() => thrownException) 207 .Verifiable(); 208 209 var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Assert); 210 211 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource); 212 213 var result = unitProcessor.TestSettings(); 214 215 processorEnvMock.Verify(); 216 217 Assert.Equal(ConfigurationTestResult.Failed, result.TestResult); 218 219 // Do not check for the type. 220 Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult); 221 Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description)); 222 Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource); 223 } 224 225 /// <summary> 226 /// Tests TestSettings when a Microsoft.PowerShell.Commands.WriteErrorException is thrown. 227 /// </summary> 228 [Fact] 229 public void TestSettings_Throws_Pwsh_WriteErrorException() 230 { 231 var thrownException = new WriteErrorException("a message"); 232 var processorEnvMock = new Mock<IProcessorEnvironment>(); 233 processorEnvMock.Setup(m => m.InvokeTestResource( 234 It.IsAny<ValueSet>(), 235 It.IsAny<string>(), 236 It.IsAny<ModuleSpecification?>())) 237 .Throws(() => thrownException) 238 .Verifiable(); 239 240 var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Assert); 241 242 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource); 243 244 var result = unitProcessor.TestSettings(); 245 246 processorEnvMock.Verify(); 247 248 Assert.Equal(ConfigurationTestResult.Failed, result.TestResult); 249 250 // Do not check for the type. 251 Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult); 252 Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description)); 253 Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource); 254 } 255 256 /// <summary> 257 /// Call ApplySettings with invalid intents. 258 /// </summary> 259 /// <param name="intent">Intent.</param> 260 [Theory] 261 [InlineData(ConfigurationUnitIntent.Inform)] 262 [InlineData(ConfigurationUnitIntent.Assert)] 263 public void ApplySettings_InvalidIntent(object intent) 264 { 265 var processorEnvMock = new Mock<IProcessorEnvironment>(); 266 var unitResource = this.CreateUnitResource(Assert.IsType<ConfigurationUnitIntent>(intent)); 267 268 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource); 269 270 Assert.Throws<NotSupportedException>(() => unitProcessor.ApplySettings()); 271 } 272 273 /// <summary> 274 /// Call ApplySettings. 275 /// </summary> 276 /// <param name="rebootRequired">Reboot required.</param> 277 [Theory] 278 [InlineData(true)] 279 [InlineData(false)] 280 public void ApplySettings_Test(bool rebootRequired) 281 { 282 var processorEnvMock = new Mock<IProcessorEnvironment>(); 283 processorEnvMock.Setup(m => m.InvokeSetResource( 284 It.IsAny<ValueSet>(), 285 It.IsAny<string>(), 286 It.IsAny<ModuleSpecification?>())) 287 .Returns(rebootRequired) 288 .Verifiable(); 289 290 var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Apply); 291 292 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource); 293 294 var result = unitProcessor.ApplySettings(); 295 296 Assert.Equal(rebootRequired, result.RebootRequired); 297 } 298 299 /// <summary> 300 /// Tests ApplySettings when a System.Management.Automation.RuntimeException is thrown. 301 /// </summary> 302 [Fact] 303 public void ApplySettings_Throws_Pwsh_RuntimeException() 304 { 305 var thrownException = new RuntimeException("a message"); 306 var processorEnvMock = new Mock<IProcessorEnvironment>(); 307 processorEnvMock.Setup(m => m.InvokeSetResource( 308 It.IsAny<ValueSet>(), 309 It.IsAny<string>(), 310 It.IsAny<ModuleSpecification?>())) 311 .Throws(() => thrownException) 312 .Verifiable(); 313 314 var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Apply); 315 316 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource); 317 318 var result = unitProcessor.ApplySettings(); 319 320 processorEnvMock.Verify(); 321 322 // Do not check for the type. 323 Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult); 324 Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description)); 325 Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource); 326 } 327 328 /// <summary> 329 /// Tests ApplySettings when a Microsoft.PowerShell.Commands.WriteErrorException is thrown. 330 /// </summary> 331 [Fact] 332 public void ApplySettings_Throws_Pwsh_WriteErrorException() 333 { 334 var thrownException = new RuntimeException("a message"); 335 var processorEnvMock = new Mock<IProcessorEnvironment>(); 336 processorEnvMock.Setup(m => m.InvokeSetResource( 337 It.IsAny<ValueSet>(), 338 It.IsAny<string>(), 339 It.IsAny<ModuleSpecification?>())) 340 .Throws(() => thrownException) 341 .Verifiable(); 342 343 var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Apply); 344 345 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource); 346 347 var result = unitProcessor.ApplySettings(); 348 349 processorEnvMock.Verify(); 350 351 // Do not check for the type. 352 Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult); 353 Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description)); 354 Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource); 355 } 356 357 /// <summary> 358 /// Tests ApplySettings in limit mode. 359 /// </summary> 360 [Fact] 361 public void ApplySettings_Test_LimitMode() 362 { 363 string theKey = "key"; 364 string theValue = "value"; 365 var valueGetResult = new ValueSet 366 { 367 { theKey, theValue }, 368 }; 369 370 var processorEnvMock = new Mock<IProcessorEnvironment>(); 371 processorEnvMock.Setup(m => m.InvokeGetResource( 372 It.IsAny<ValueSet>(), 373 It.IsAny<string>(), 374 It.IsAny<ModuleSpecification?>())) 375 .Returns(valueGetResult) 376 .Verifiable(); 377 378 var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Apply); 379 380 var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource, true); 381 382 // GetSettings can be called multiple times. 383 var getResult = unitProcessor.GetSettings(); 384 getResult = unitProcessor.GetSettings(); 385 386 // TestSettings can be called only once. 387 var testResult = unitProcessor.TestSettings(); 388 Assert.Throws<System.InvalidOperationException>(() => unitProcessor.TestSettings()); 389 390 // ApplySettings can be called only once. 391 var applyResult = unitProcessor.ApplySettings(); 392 Assert.Throws<System.InvalidOperationException>(() => unitProcessor.ApplySettings()); 393 } 394 395 private ConfigurationUnitAndResource CreateUnitResource(ConfigurationUnitIntent intent) 396 { 397 string resourceName = "xResourceName"; 398 return new ConfigurationUnitAndResource( 399 new ConfigurationUnitAndModule( 400 new ConfigurationUnit 401 { 402 Type = resourceName, 403 Intent = intent, 404 }, 405 string.Empty), 406 new DscResourceInfoInternal(resourceName, null, null)); 407 } 408 } 409 }