winget-cli

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

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 }