Skip to content

Commit

Permalink
Enable PsesInternalHostTests (previously PowerShellContextTests)
Browse files Browse the repository at this point in the history
  • Loading branch information
andyleejordan committed Dec 28, 2021
1 parent bb17dbc commit 7c1a5cc
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 188 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal class PsesInternalHost : PSHost, IHostSupportsInteractiveSession, IRuns

private readonly ILanguageServerFacade _languageServer;

private readonly HostStartupInfo _hostInfo;
internal readonly HostStartupInfo _hostInfo;

private readonly BlockingConcurrentDeque<ISynchronousTask> _taskQueue;

Expand Down Expand Up @@ -216,12 +216,7 @@ public async Task<bool> TryStartAsync(HostStartOptions startOptions, Cancellatio

if (startOptions.LoadProfiles)
{
await ExecuteDelegateAsync(
"LoadProfiles",
new PowerShellExecutionOptions { MustRunInForeground = true, ThrowOnError = false },
(pwsh, _) => pwsh.LoadProfiles(_hostInfo.ProfilePaths),
cancellationToken).ConfigureAwait(false);

await LoadHostProfilesAsync(cancellationToken).ConfigureAwait(false);
_logger.LogInformation("Profiles loaded");
}

Expand Down Expand Up @@ -391,6 +386,15 @@ public void InvokePSDelegate(string representation, ExecutionOptions executionOp
task.ExecuteAndGetResult(cancellationToken);
}

internal Task LoadHostProfilesAsync(CancellationToken cancellationToken)
{
return ExecuteDelegateAsync(
"LoadProfiles",
new PowerShellExecutionOptions { MustRunInForeground = true, ThrowOnError = false },
(pwsh, _) => pwsh.LoadProfiles(_hostInfo.ProfilePaths),
cancellationToken);
}

public Task SetInitialWorkingDirectoryAsync(string path, CancellationToken cancellationToken)
{
InitialWorkingDirectory = path;
Expand Down Expand Up @@ -703,7 +707,7 @@ private static PowerShell CreateNestedPowerShell(RunspaceInfo currentRunspace)
return pwsh;
}

private static PowerShell CreatePowerShellForRunspace(Runspace runspace)
internal static PowerShell CreatePowerShellForRunspace(Runspace runspace)
{
var pwsh = PowerShell.Create();
pwsh.Runspace = runspace;
Expand Down Expand Up @@ -751,7 +755,7 @@ private static PowerShell CreatePowerShellForRunspace(Runspace runspace)
return (pwsh, engineIntrinsics);
}

private Runspace CreateInitialRunspace(InitialSessionState initialSessionState)
internal Runspace CreateInitialRunspace(InitialSessionState initialSessionState)
{
Runspace runspace = RunspaceFactory.CreateRunspace(PublicHost, initialSessionState);

Expand Down Expand Up @@ -919,7 +923,7 @@ private Task PopOrReinitializeRunspaceAsync()
CancellationToken.None);
}

private bool TryLoadPSReadLine(PowerShell pwsh, EngineIntrinsics engineIntrinsics, out IReadLine psrlReadLine)
internal bool TryLoadPSReadLine(PowerShell pwsh, EngineIntrinsics engineIntrinsics, out IReadLine psrlReadLine)
{
psrlReadLine = null;
try
Expand Down
178 changes: 0 additions & 178 deletions test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs

This file was deleted.

150 changes: 150 additions & 0 deletions test/PowerShellEditorServices.Test/Session/PsesInternalHostTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Host;
using Xunit;

namespace Microsoft.PowerShell.EditorServices.Test.Console
{
using System.Management.Automation;
using System.Management.Automation.Runspaces;

public class PsesInternalHostTests : IDisposable
{
private readonly PsesInternalHost psesHost;

public PsesInternalHostTests()
{
psesHost = PsesHostFactory.Create(NullLoggerFactory.Instance);
}

public void Dispose()
{
psesHost.StopAsync().Wait();
GC.SuppressFinalize(this);
}

[Trait("Category", "PsesInternalHost")]
[Fact]
public async Task CanExecutePSCommand()
{
Assert.True(psesHost.IsRunning);
var command = new PSCommand().AddScript("$a = \"foo\"; $a");
var task = psesHost.ExecutePSCommandAsync<string>(command, CancellationToken.None);
var result = await task.ConfigureAwait(true);
Assert.Equal("foo", result[0]);
}

[Trait("Category", "PsesInternalHost")]
[Fact]
public async Task CanQueueParallelPSCommands()
{
// Concurrently initiate 4 requests in the session.
Task taskOne = psesHost.ExecutePSCommandAsync(
new PSCommand().AddScript("$x = 100"),
CancellationToken.None);

Task taskTwo = psesHost.ExecutePSCommandAsync(
new PSCommand().AddScript("$x += 200"),
CancellationToken.None);

Task taskThree = psesHost.ExecutePSCommandAsync(
new PSCommand().AddScript("$x = $x / 100"),
CancellationToken.None);

Task<IReadOnlyList<int>> resultTask = psesHost.ExecutePSCommandAsync<int>(
new PSCommand().AddScript("$x"),
CancellationToken.None);

// Wait for all of the executes to complete.
await Task.WhenAll(taskOne, taskTwo, taskThree, resultTask).ConfigureAwait(true);

// Sanity checks
Assert.Equal(RunspaceState.Opened, psesHost.Runspace.RunspaceStateInfo.State);

// 100 + 200 = 300, then divided by 100 is 3. We are ensuring that
// the commands were executed in the sequence they were called.
Assert.Equal(3, (await resultTask.ConfigureAwait(true))[0]);
}

[Trait("Category", "PsesInternalHost")]
[Fact]
public async Task CanCancelExecutionWithToken()
{
_ = await Assert.ThrowsAsync<TaskCanceledException>(() =>
{
return psesHost.ExecutePSCommandAsync(
new PSCommand().AddScript("Start-Sleep 10"),
new CancellationTokenSource(1000).Token);
}).ConfigureAwait(true);
}

[Trait("Category", "PsesInternalHost")]
[Fact]
public async Task CanCancelExecutionWithMethod()
{
var executeTask = psesHost.ExecutePSCommandAsync(
new PSCommand().AddScript("Start-Sleep 10"),
CancellationToken.None);

// Wait until our task has started.
Thread.Sleep(2000);
psesHost.CancelCurrentTask();
_ = await Assert.ThrowsAsync<TaskCanceledException>(() => executeTask).ConfigureAwait(true);
Assert.True(executeTask.IsCanceled);
}


[Trait("Category", "PsesInternalHost")]
[Fact]
public async Task CanResolveAndLoadProfilesForHostId()
{
string[] expectedProfilePaths =
new string[]
{
PsesHostFactory.TestProfilePaths.AllUsersAllHosts,
PsesHostFactory.TestProfilePaths.AllUsersCurrentHost,
PsesHostFactory.TestProfilePaths.CurrentUserAllHosts,
PsesHostFactory.TestProfilePaths.CurrentUserCurrentHost
};

// Load the profiles for the test host name
await psesHost.LoadHostProfilesAsync(CancellationToken.None).ConfigureAwait(true);

// Ensure that all the paths are set in the correct variables
// and that the current user's host profile got loaded
PSCommand psCommand = new PSCommand().AddScript(
"\"$($profile.AllUsersAllHosts) " +
"$($profile.AllUsersCurrentHost) " +
"$($profile.CurrentUserAllHosts) " +
"$($profile.CurrentUserCurrentHost) " +
"$(Assert-ProfileLoaded)\"");

var result = await psesHost.ExecutePSCommandAsync<string>(psCommand, CancellationToken.None).ConfigureAwait(true);

string expectedString =
string.Format(
"{0} True",
string.Join(
" ",
expectedProfilePaths));

Assert.Equal(expectedString, result[0], ignoreCase: true);
}

[Trait("Category", "PSReadLine")]
[Fact]
public void CanLoadPSReadLine()
{
Runspace runspace = psesHost.CreateInitialRunspace(psesHost._hostInfo.InitialSessionState);
PowerShell pwsh = PsesInternalHost.CreatePowerShellForRunspace(runspace);
var engineIntrinsics = (EngineIntrinsics)runspace.SessionStateProxy.GetVariable("ExecutionContext");
Assert.True(psesHost.TryLoadPSReadLine(pwsh, engineIntrinsics, out _));
}
}
}

0 comments on commit 7c1a5cc

Please sign in to comment.