Skip to content

Commit c667d39

Browse files
Skip all debug adapter E2E tests on Windows PowerShell
The CI hang is in the shared per-test InitializeAsync that starts the PSES debug-adapter server, not in any single test, so skipping only CanAttachScriptWithPathMappings just promotes the next test to first victim. Each test pays a fresh cold-start, and intermittently any one of them can be the test that wedges on the 20260614 runner image. Broaden the discovery-time Windows PowerShell skip to the entire DebugAdapterProtocolMessageTests class: add a SkippableTheory companion to the existing SkippableFact variant, share the skip reason, and apply the attributes to all test methods. The pwsh (.NET 8) E2E suite still runs the full set, so only in-box Windows PowerShell debug-adapter coverage is paused, pending a real fix tracked in #2323. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent c71da92 commit c667d39

3 files changed

Lines changed: 57 additions & 20 deletions

File tree

test/PowerShellEditorServices.Test.E2E/DebugAdapterProtocolMessageTests.cs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@
2424

2525
namespace PowerShellEditorServices.Test.E2E
2626
{
27+
/// <remarks>
28+
/// Every test in this class is skipped at discovery time on in-box Windows
29+
/// PowerShell (via <see cref="SkippableFactOnWindowsPowerShellAttribute"/> and
30+
/// <see cref="SkippableTheoryOnWindowsPowerShellAttribute"/>) because the shared
31+
/// <see cref="InitializeAsync"/> debug-adapter startup can wedge there since the
32+
/// 20260614 runner image, riding the job timeout. See
33+
/// https://github.com/PowerShell/PowerShellEditorServices/issues/2323.
34+
/// </remarks>
2735
[Trait("Category", "DAP")]
2836
// ITestOutputHelper is injected by XUnit
2937
// https://xunit.net/docs/capturing-output
@@ -256,7 +264,7 @@ private async Task<string> ReadScriptLogLineAsync()
256264
}
257265
}
258266

259-
[Fact]
267+
[SkippableFactOnWindowsPowerShell]
260268
public void CanInitializeWithCorrectServerSettings()
261269
{
262270
Assert.True(client.ServerSettings.SupportsConditionalBreakpoints);
@@ -268,7 +276,7 @@ public void CanInitializeWithCorrectServerSettings()
268276
Assert.True(client.ServerSettings.SupportsDelayedStackTraceLoading);
269277
}
270278

271-
[Fact]
279+
[SkippableFactOnWindowsPowerShell]
272280
public async Task UsesDotSourceOperatorAndQuotesAsync()
273281
{
274282
string filePath = NewTestFile(GenerateLoggingScript("$($MyInvocation.Line)"));
@@ -280,7 +288,7 @@ public async Task UsesDotSourceOperatorAndQuotesAsync()
280288
Assert.StartsWith(". '", actual);
281289
}
282290

283-
[Fact]
291+
[SkippableFactOnWindowsPowerShell]
284292
public async Task UsesCallOperatorWithSettingAsync()
285293
{
286294
string filePath = NewTestFile(GenerateLoggingScript("$($MyInvocation.Line)"));
@@ -292,7 +300,7 @@ public async Task UsesCallOperatorWithSettingAsync()
292300
Assert.StartsWith("& '", actual);
293301
}
294302

295-
[Fact]
303+
[SkippableFactOnWindowsPowerShell]
296304
public async Task CanLaunchScriptWithNoBreakpointsAsync()
297305
{
298306
string filePath = NewTestFile(GenerateLoggingScript("works"));
@@ -306,7 +314,7 @@ public async Task CanLaunchScriptWithNoBreakpointsAsync()
306314
Assert.Equal("works", actual);
307315
}
308316

309-
[SkippableFact]
317+
[SkippableFactOnWindowsPowerShell]
310318
public async Task CanSetBreakpointsAsync()
311319
{
312320
Skip.If(PsesStdioLanguageServerProcessHost.RunningInConstrainedLanguageMode,
@@ -357,7 +365,7 @@ public async Task CanSetBreakpointsAsync()
357365
Assert.Equal("after breakpoint", afterBreakpointActual);
358366
}
359367

360-
[SkippableFact]
368+
[SkippableFactOnWindowsPowerShell]
361369
public async Task FailsIfStacktraceRequestedWhenNotPaused()
362370
{
363371
Skip.If(PsesStdioLanguageServerProcessHost.RunningInConstrainedLanguageMode,
@@ -388,7 +396,7 @@ await Assert.ThrowsAsync<JsonRpcException>(() => client.RequestStackTrace(
388396
));
389397
}
390398

391-
[SkippableFact]
399+
[SkippableFactOnWindowsPowerShell]
392400
public async Task SendsInitialLabelBreakpointForPerformanceReasons()
393401
{
394402
Skip.If(PsesStdioLanguageServerProcessHost.RunningInConstrainedLanguageMode,
@@ -446,7 +454,7 @@ public async Task SendsInitialLabelBreakpointForPerformanceReasons()
446454
// PowerShell, we avoid all issues with our test project (and the xUnit executable) not
447455
// having System.Windows.Forms deployed, and can instead rely on the Windows Global Assembly
448456
// Cache (GAC) to find it.
449-
[SkippableFact]
457+
[SkippableFactOnWindowsPowerShell]
450458
public async Task CanStepPastSystemWindowsForms()
451459
{
452460
Skip.IfNot(PsesStdioLanguageServerProcessHost.IsWindowsPowerShell,
@@ -489,7 +497,7 @@ public async Task CanStepPastSystemWindowsForms()
489497
// commented. Since in some cases (such as Windows PowerShell, or the script not having a
490498
// backing ScriptFile) we just wrap the script with braces, we had a bug where the last
491499
// brace would be after the comment. We had to ensure we wrapped with newlines instead.
492-
[Fact]
500+
[SkippableFactOnWindowsPowerShell]
493501
public async Task CanLaunchScriptWithCommentedLastLineAsync()
494502
{
495503
string script = GenerateLoggingScript("$($MyInvocation.Line)", "$(1+1)") + "# a comment at the end";
@@ -513,7 +521,7 @@ public async Task CanLaunchScriptWithCommentedLastLineAsync()
513521
Assert.Equal("2", await ReadScriptLogLineAsync());
514522
}
515523

516-
[SkippableFact]
524+
[SkippableFactOnWindowsPowerShell]
517525
public async Task CanRunPesterTestFile()
518526
{
519527
Skip.If(true, "Pester test is broken.");
@@ -558,7 +566,7 @@ public async Task CanRunPesterTestFile()
558566
[InlineData("-ProcessId 1234 -RunspaceId 5678", null, null, 1234, 5678, null)]
559567
[InlineData("-ProcessId 1234 -RunspaceId 5678 -ComputerName comp", "comp", null, 1234, 5678, null)]
560568
[InlineData("-CustomPipeName testpipe -RunspaceName rs-name", null, "testpipe", 0, 0, "rs-name")]
561-
[SkippableTheory]
569+
[SkippableTheoryOnWindowsPowerShell]
562570
public async Task CanLaunchScriptWithNewChildAttachSession(
563571
string paramString,
564572
string? expectedComputerName,
@@ -596,7 +604,7 @@ public async Task CanLaunchScriptWithNewChildAttachSession(
596604
await terminatedTcs.Task;
597605
}
598606

599-
[SkippableFact]
607+
[SkippableFactOnWindowsPowerShell]
600608
public async Task CanLaunchScriptWithNewChildAttachSessionAsJob()
601609
{
602610
Skip.If(PsesStdioLanguageServerProcessHost.RunningInConstrainedLanguageMode,
@@ -630,13 +638,8 @@ public async Task CanLaunchScriptWithNewChildAttachSessionAsJob()
630638
await terminatedTcs.Task;
631639
}
632640

633-
// NOTE: This passes against PowerShell Core but hangs against in-box Windows
634-
// PowerShell since the windows-2025-vs2026 runner image moved from 20260608 to
635-
// 20260614, where it wedges during server setup and rides the job timeout. The
636-
// skip must happen at discovery time (via the attribute) rather than with an
637-
// in-body Skip.If, because xUnit runs InitializeAsync (which is where the hang
638-
// occurs) before the test body. Skipped on Windows PowerShell pending a real
639-
// fix; see https://github.com/PowerShell/PowerShellEditorServices/issues/2323.
641+
// Timeout is a per-test backstop; the Windows PowerShell skip happens at
642+
// discovery time via the attribute (see the class remarks).
640643
[SkippableFactOnWindowsPowerShell(Timeout = 15000)]
641644
public async Task CanAttachScriptWithPathMappings()
642645
{

test/PowerShellEditorServices.Test.E2E/Hosts/SkippableFactOnWindowsPowerShellAttribute.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@
66

77
namespace PowerShellEditorServices.Test.E2E;
88

9+
/// <summary>
10+
/// The shared skip reason used by the discovery-time Windows PowerShell skip
11+
/// attributes for the debug adapter end-to-end tests.
12+
/// </summary>
13+
internal static class WindowsPowerShellDebugAdapterSkip
14+
{
15+
public const string Reason = "The debug adapter can wedge during startup on in-box Windows PowerShell since the 20260614 runner image; see https://github.com/PowerShell/PowerShellEditorServices/issues/2323.";
16+
}
17+
918
/// <summary>
1019
/// A <see cref="SkippableFactAttribute"/> that additionally skips the test at
1120
/// <em>discovery</em> time when running under in-box Windows PowerShell.
@@ -28,7 +37,7 @@ public SkippableFactOnWindowsPowerShellAttribute()
2837
{
2938
if (PsesStdioLanguageServerProcessHost.IsWindowsPowerShell)
3039
{
31-
Skip = "Attach wedges during setup on Windows PowerShell since the 20260614 runner image; see https://github.com/PowerShell/PowerShellEditorServices/issues/2323.";
40+
Skip = WindowsPowerShellDebugAdapterSkip.Reason;
3241
}
3342
}
3443
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using Xunit;
5+
using Xunit.Sdk;
6+
7+
namespace PowerShellEditorServices.Test.E2E;
8+
9+
/// <summary>
10+
/// A <see cref="SkippableTheoryAttribute"/> that additionally skips the theory at
11+
/// <em>discovery</em> time when running under in-box Windows PowerShell. See
12+
/// <see cref="SkippableFactOnWindowsPowerShellAttribute"/> for why the skip must
13+
/// happen at discovery time rather than via an in-body <see cref="Skip"/> call.
14+
/// </summary>
15+
[XunitTestCaseDiscoverer("Xunit.Sdk.SkippableTheoryDiscoverer", "Xunit.SkippableFact")]
16+
public sealed class SkippableTheoryOnWindowsPowerShellAttribute : SkippableTheoryAttribute
17+
{
18+
public SkippableTheoryOnWindowsPowerShellAttribute()
19+
{
20+
if (PsesStdioLanguageServerProcessHost.IsWindowsPowerShell)
21+
{
22+
Skip = WindowsPowerShellDebugAdapterSkip.Reason;
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)