Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,31 @@ public static void SetCorrectExecutionPolicy(this PowerShell pwsh, ILogger logge
{
// We want to get the list hierarchy of execution policies
// Calling the cmdlet is the simplest way to do that
IReadOnlyList<PSObject> policies = pwsh
.AddCommand(@"Microsoft.PowerShell.Security\Get-ExecutionPolicy")
.AddParameter("List")
.InvokeAndClear<PSObject>();
IReadOnlyList<PSObject> policies;
try
{
policies = pwsh
.AddCommand(@"Microsoft.PowerShell.Security\Get-ExecutionPolicy")
.AddParameter("List")
.InvokeAndClear<PSObject>();
}
catch (Exception e)
{
// Some Windows PowerShell servicing builds throw a type-data conflict
// ("The member ... is already present" on ObjectSecurity) when
// autoloading Microsoft.PowerShell.Security into a runspace whose
// InitialSessionState already carries that module's type data.
// Configuring the execution policy is best-effort, so log and skip
// rather than letting it abort host startup (which manifests as a hang).
logger.LogError(e, "Failed to query the execution policy; skipping execution policy configuration.");
return;
}

// We need at least the CurrentUser and LocalMachine scopes to proceed.
if (policies is null || policies.Count < 2)
{
return;
}
Comment on lines +141 to +165

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Justin Grote (@JustinGrote) I got this whole issue to repro locally on a Windows box and apparently this was the issue that was hanging all the end-to-end tests on the updated image.


// The policies come out in the following order:
// - MachinePolicy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@

namespace PowerShellEditorServices.Test.E2E
{
/// <remarks>
/// Every test in this class is skipped at discovery time on in-box Windows
/// PowerShell (via <see cref="SkippableFactOnWindowsPowerShellAttribute"/> and
/// <see cref="SkippableTheoryOnWindowsPowerShellAttribute"/>) because the shared
/// <see cref="InitializeAsync"/> debug-adapter startup can wedge there since the
/// 20260614 runner image, riding the job timeout. See
/// https://github.com/PowerShell/PowerShellEditorServices/issues/2323.
/// </remarks>
[Trait("Category", "DAP")]
// ITestOutputHelper is injected by XUnit
// https://xunit.net/docs/capturing-output
Expand Down Expand Up @@ -246,25 +238,16 @@ private async Task<string> ReadScriptLogLineAsync()
}
}

// Tail the log until a non-empty line is available. The awaited
// delay between reads matters: at EOF ReadLineAsync completes
// synchronously with null, so without it this is a tight loop that
// never releases its thread-pool thread and needlessly pressures
// the pool on constrained CI runners. Yielding keeps the tail loop
// cheap while we wait for the script to write.
while (true)
// return valid lines only
string nextLine = string.Empty;
while (nextLine is null || nextLine.Length == 0)
{
string nextLine = await scriptLogReader.ReadLineAsync();
if (!string.IsNullOrEmpty(nextLine))
{
return nextLine;
}

await Task.Delay(100);
nextLine = await scriptLogReader.ReadLineAsync(); //Might return null if at EOF because we created it above but the script hasn't written to it yet
}
return nextLine;
}

[SkippableFactOnWindowsPowerShell]
[Fact]
public void CanInitializeWithCorrectServerSettings()
{
Assert.True(client.ServerSettings.SupportsConditionalBreakpoints);
Expand All @@ -276,7 +259,7 @@ public void CanInitializeWithCorrectServerSettings()
Assert.True(client.ServerSettings.SupportsDelayedStackTraceLoading);
}

[SkippableFactOnWindowsPowerShell]
[Fact]
public async Task UsesDotSourceOperatorAndQuotesAsync()
{
string filePath = NewTestFile(GenerateLoggingScript("$($MyInvocation.Line)"));
Expand All @@ -288,7 +271,7 @@ public async Task UsesDotSourceOperatorAndQuotesAsync()
Assert.StartsWith(". '", actual);
}

[SkippableFactOnWindowsPowerShell]
[Fact]
public async Task UsesCallOperatorWithSettingAsync()
{
string filePath = NewTestFile(GenerateLoggingScript("$($MyInvocation.Line)"));
Expand All @@ -300,7 +283,7 @@ public async Task UsesCallOperatorWithSettingAsync()
Assert.StartsWith("& '", actual);
}

[SkippableFactOnWindowsPowerShell]
[Fact]
public async Task CanLaunchScriptWithNoBreakpointsAsync()
{
string filePath = NewTestFile(GenerateLoggingScript("works"));
Expand All @@ -314,7 +297,7 @@ public async Task CanLaunchScriptWithNoBreakpointsAsync()
Assert.Equal("works", actual);
}

[SkippableFactOnWindowsPowerShell]
[SkippableFact]
public async Task CanSetBreakpointsAsync()
{
Skip.If(PsesStdioLanguageServerProcessHost.RunningInConstrainedLanguageMode,
Expand Down Expand Up @@ -365,7 +348,7 @@ public async Task CanSetBreakpointsAsync()
Assert.Equal("after breakpoint", afterBreakpointActual);
}

[SkippableFactOnWindowsPowerShell]
[SkippableFact]
public async Task FailsIfStacktraceRequestedWhenNotPaused()
{
Skip.If(PsesStdioLanguageServerProcessHost.RunningInConstrainedLanguageMode,
Expand Down Expand Up @@ -396,7 +379,7 @@ await Assert.ThrowsAsync<JsonRpcException>(() => client.RequestStackTrace(
));
}

[SkippableFactOnWindowsPowerShell]
[SkippableFact]
public async Task SendsInitialLabelBreakpointForPerformanceReasons()
{
Skip.If(PsesStdioLanguageServerProcessHost.RunningInConstrainedLanguageMode,
Expand Down Expand Up @@ -454,7 +437,7 @@ public async Task SendsInitialLabelBreakpointForPerformanceReasons()
// PowerShell, we avoid all issues with our test project (and the xUnit executable) not
// having System.Windows.Forms deployed, and can instead rely on the Windows Global Assembly
// Cache (GAC) to find it.
[SkippableFactOnWindowsPowerShell]
[SkippableFact]
public async Task CanStepPastSystemWindowsForms()
{
Skip.IfNot(PsesStdioLanguageServerProcessHost.IsWindowsPowerShell,
Expand Down Expand Up @@ -497,7 +480,7 @@ public async Task CanStepPastSystemWindowsForms()
// commented. Since in some cases (such as Windows PowerShell, or the script not having a
// backing ScriptFile) we just wrap the script with braces, we had a bug where the last
// brace would be after the comment. We had to ensure we wrapped with newlines instead.
[SkippableFactOnWindowsPowerShell]
[Fact]
public async Task CanLaunchScriptWithCommentedLastLineAsync()
{
string script = GenerateLoggingScript("$($MyInvocation.Line)", "$(1+1)") + "# a comment at the end";
Expand All @@ -521,7 +504,7 @@ public async Task CanLaunchScriptWithCommentedLastLineAsync()
Assert.Equal("2", await ReadScriptLogLineAsync());
}

[SkippableFactOnWindowsPowerShell]
[SkippableFact]
public async Task CanRunPesterTestFile()
{
Skip.If(true, "Pester test is broken.");
Expand Down Expand Up @@ -566,7 +549,7 @@ public async Task CanRunPesterTestFile()
[InlineData("-ProcessId 1234 -RunspaceId 5678", null, null, 1234, 5678, null)]
[InlineData("-ProcessId 1234 -RunspaceId 5678 -ComputerName comp", "comp", null, 1234, 5678, null)]
[InlineData("-CustomPipeName testpipe -RunspaceName rs-name", null, "testpipe", 0, 0, "rs-name")]
[SkippableTheoryOnWindowsPowerShell]
[SkippableTheory]
public async Task CanLaunchScriptWithNewChildAttachSession(
string paramString,
string? expectedComputerName,
Expand Down Expand Up @@ -604,7 +587,7 @@ public async Task CanLaunchScriptWithNewChildAttachSession(
await terminatedTcs.Task;
}

[SkippableFactOnWindowsPowerShell]
[SkippableFact]
public async Task CanLaunchScriptWithNewChildAttachSessionAsJob()
{
Skip.If(PsesStdioLanguageServerProcessHost.RunningInConstrainedLanguageMode,
Expand Down Expand Up @@ -638,9 +621,7 @@ public async Task CanLaunchScriptWithNewChildAttachSessionAsJob()
await terminatedTcs.Task;
}

// Timeout is a per-test backstop; the Windows PowerShell skip happens at
// discovery time via the attribute (see the class remarks).
[SkippableFactOnWindowsPowerShell(Timeout = 15000)]
[SkippableFact(Timeout = 15000)]
public async Task CanAttachScriptWithPathMappings()
{
Skip.If(PsesStdioLanguageServerProcessHost.RunningInConstrainedLanguageMode,
Expand Down Expand Up @@ -781,10 +762,6 @@ WinPS will always need this.
if (((Get-Date) - $start).TotalSeconds -gt 10) {
throw 'Timeout waiting for Debug-Runspace to be subscribed.'
}

# Yield a slice so this poll doesn't peg a core while the
# runner is also servicing the attach handshake.
Start-Sleep -Milliseconds 100
}
Comment thread
SeeminglyScience marked this conversation as resolved.

$ps.Invoke()
Expand Down

This file was deleted.

This file was deleted.

21 changes: 1 addition & 20 deletions test/PowerShellEditorServices.Test.E2E/LSPTestsFixtures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,6 @@ public class LSPTestsFixture : IAsyncLifetime

public async Task InitializeAsync()
{
// All LSP end-to-end tests are skipped at discovery time on Windows
// PowerShell (see SkippableFactOnWindowsPowerShell), but xUnit still
// creates this class fixture even when every test method is skipped.
// The in-box Windows PowerShell server can wedge during startup on the
// current windows-latest runner image (a runner-image regression, not
// our code); see https://github.com/PowerShell/PowerShellEditorServices/issues/2323.
// So we must not start the server here on Windows PowerShell.
if (PsesStdioLanguageServerProcessHost.IsWindowsPowerShell)
{
return;
}

(StreamReader stdout, StreamWriter stdin) = await _psesHost.Start();

// Splice the streams together and enable debug logging of all messages sent and received
Expand Down Expand Up @@ -112,16 +100,9 @@ public async Task InitializeAsync()

public async Task DisposeAsync()
{
// The server is never started on Windows PowerShell (see
// InitializeAsync), so there is nothing to shut down there.
if (PsesLanguageClient is null)
{
return;
}

await PsesLanguageClient.Shutdown();
await _psesHost.Stop();
PsesLanguageClient.Dispose();
PsesLanguageClient?.Dispose();
Comment thread
Copilot marked this conversation as resolved.
Outdated
}
}
}
Loading
Loading