ShutdownTests.cs (7399B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="ShutdownTests.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.Threading; 11 using System.Threading.Tasks; 12 using Microsoft.Management.Configuration.UnitTests.Fixtures; 13 using Microsoft.Management.Configuration.UnitTests.Helpers; 14 using WinGetTestCommon; 15 using Xunit; 16 using Xunit.Abstractions; 17 18 /// <summary> 19 /// Unit tests for running test on the processor. 20 /// </summary> 21 [Collection("UnitTestCollection")] 22 [OutOfProc] 23 public class ShutdownTests : ConfigurationProcessorTestBase 24 { 25 /// <summary> 26 /// Initializes a new instance of the <see cref="ShutdownTests"/> class. 27 /// </summary> 28 /// <param name="fixture">Unit test fixture.</param> 29 /// <param name="log">Log helper.</param> 30 public ShutdownTests(UnitTestFixture fixture, ITestOutputHelper log) 31 : base(fixture, log) 32 { 33 } 34 35 /// <summary> 36 /// Initiates a shutdown on the process when it is running a synchronous operation. 37 /// </summary> 38 [Fact] 39 public void ShutdownSynchronization_SyncCall() 40 { 41 this.Fixture.RecreateStatics(); 42 43 ConfigurationSet configurationSet = this.ConfigurationSet(); 44 ConfigurationUnit configurationUnitWaits = this.ConfigurationUnit(); 45 ConfigurationUnit configurationUnitWorks = this.ConfigurationUnit(); 46 configurationSet.Units = new ConfigurationUnit[] { configurationUnitWaits, configurationUnitWorks }; 47 48 TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); 49 TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); 50 TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnitWaits); 51 52 ManualResetEvent isWaiting = new ManualResetEvent(false); 53 ManualResetEvent waitingOn = new ManualResetEvent(false); 54 unitProcessor.TestSettingsDelegate = () => 55 { 56 isWaiting.Set(); 57 waitingOn.WaitOne(); 58 return new TestSettingsResultInstance(configurationUnitWaits) { TestResult = ConfigurationTestResult.Positive }; 59 }; 60 61 ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); 62 63 TestConfigurationSetResult? result = null; 64 Exception? exception = null; 65 66 ManualResetEvent syncCallDone = new ManualResetEvent(false); 67 Thread thread = new Thread(() => 68 { 69 try 70 { 71 result = processor.TestSet(configurationSet); 72 } 73 catch (Exception ex) 74 { 75 exception = ex; 76 } 77 78 syncCallDone.Set(); 79 }); 80 thread.Start(); 81 82 Assert.True(isWaiting.WaitOne(5000)); 83 84 var servers = WinGetServerInstance.GetInstances(); 85 Assert.Single(servers); 86 87 var server = servers[0]; 88 Assert.True(server.HasWindow); 89 90 // This is the call pattern from Windows 91 this.SendMessageAndLog(server, WindowMessage.QueryEndSession); 92 93 Thread thread2 = new Thread(() => 94 { 95 // Release the wait after initiating the shutdown, but before waiting on it 96 waitingOn.Set(); 97 }); 98 thread2.Start(); 99 100 this.SendMessageAndLog(server, WindowMessage.EndSession); 101 this.SendMessageAndLog(server, WindowMessage.Close); 102 103 Assert.True(syncCallDone.WaitOne(5000)); 104 105 Assert.NotNull(exception); 106 107 Assert.True(server.Process.WaitForExit(5000)); 108 } 109 110 /// <summary> 111 /// Initiates a shutdown on the process when it is running an asynchronous operation. 112 /// </summary> 113 [Fact] 114 public void ShutdownSynchronization_AsyncCall() 115 { 116 this.Fixture.RecreateStatics(); 117 118 ConfigurationSet configurationSet = this.ConfigurationSet(); 119 ConfigurationUnit configurationUnitWaits = this.ConfigurationUnit(); 120 ConfigurationUnit configurationUnitWorks = this.ConfigurationUnit(); 121 configurationSet.Units = new ConfigurationUnit[] { configurationUnitWaits, configurationUnitWorks }; 122 123 TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); 124 TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); 125 TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnitWaits); 126 127 ManualResetEvent isWaiting = new ManualResetEvent(false); 128 ManualResetEvent waitingOn = new ManualResetEvent(false); 129 unitProcessor.TestSettingsDelegate = () => 130 { 131 isWaiting.Set(); 132 waitingOn.WaitOne(); 133 return new TestSettingsResultInstance(configurationUnitWaits) { TestResult = ConfigurationTestResult.Positive }; 134 }; 135 136 ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); 137 138 var operation = processor.TestSetAsync(configurationSet); 139 Assert.True(isWaiting.WaitOne(5000)); 140 141 var servers = WinGetServerInstance.GetInstances(); 142 Assert.Single(servers); 143 144 var server = servers[0]; 145 Assert.True(server.HasWindow); 146 147 // This is the call pattern from Windows 148 this.SendMessageAndLog(server, WindowMessage.QueryEndSession); 149 150 Thread thread2 = new Thread(() => 151 { 152 // Release the wait after initiating the shutdown, but before waiting on it 153 waitingOn.Set(); 154 }); 155 thread2.Start(); 156 157 this.SendMessageAndLog(server, WindowMessage.EndSession); 158 this.SendMessageAndLog(server, WindowMessage.Close); 159 160 Assert.ThrowsAny<Exception>(() => operation.GetAwaiter().GetResult()); 161 162 Assert.True(server.Process.WaitForExit(5000)); 163 } 164 165 private void SendMessageAndLog(WinGetServerInstance server, WindowMessage message) 166 { 167 this.Log.WriteLine($"Sending message {message} to process {server.Process.Id}..."); 168 try 169 { 170 if (server.SendMessage(message)) 171 { 172 this.Log.WriteLine("... succeeded."); 173 } 174 else 175 { 176 this.Log.WriteLine("... failed."); 177 } 178 } 179 catch (Exception e) 180 { 181 this.Log.WriteLine($"... had exception: {e.Message}"); 182 } 183 } 184 } 185 }