Skip to content

Commit

Permalink
Merge pull request #1542 from PowerShell/andschwa/forms-test
Browse files Browse the repository at this point in the history
Add regression test for `System.Windows.Forms` bug
  • Loading branch information
andyleejordan authored Aug 19, 2021
2 parents 69a0b04 + cd29c49 commit 5bb5b8a
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 31 deletions.
4 changes: 2 additions & 2 deletions src/PowerShellEditorServices/PowerShellEditorServices.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.FileSystemGlobbing" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="OmniSharp.Extensions.LanguageServer" Version="0.19.2" />
<PackageReference Include="OmniSharp.Extensions.DebugAdapter.Server" Version="0.19.2" />
<PackageReference Include="OmniSharp.Extensions.LanguageServer" Version="0.19.3" />
<PackageReference Include="OmniSharp.Extensions.DebugAdapter.Server" Version="0.19.3" />
<PackageReference Include="PowerShellStandard.Library" Version="5.1.1" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,5 +228,64 @@ public async Task CanSetBreakpointsAsync()
(i) => Assert.Equal("at breakpoint", i),
(i) => Assert.Equal("after breakpoint", i));
}

// This is a regression test for a bug where user code causes a new synchronization context
// to be created, breaking the extension. It's most evident when debugging PowerShell
// scripts that use System.Windows.Forms. It required fixing both Editor Services and
// OmniSharp.
//
// This test depends on PowerShell being able to load System.Windows.Forms, which only works
// reliably with Windows PowerShell. It works with PowerShell Core in the real-world;
// however, our host executable is xUnit, not PowerShell. So by restricting to Windows
// 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.
[Trait("Category", "DAP")]
[SkippableFact]
public async Task CanStepPastSystemWindowsForms()
{
Skip.IfNot(PsesStdioProcess.IsWindowsPowerShell);
Skip.If(PsesStdioProcess.RunningInConstainedLanguageMode);

string filePath = NewTestFile(string.Join(Environment.NewLine, new []
{
"Add-Type -AssemblyName System.Windows.Forms",
"$form = New-Object System.Windows.Forms.Form",
"Write-Host $form"
}));

await PsesDebugAdapterClient.LaunchScript(filePath, Started).ConfigureAwait(false);

var setBreakpointsResponse = await PsesDebugAdapterClient.SetFunctionBreakpoints(
new SetFunctionBreakpointsArguments
{
Breakpoints = new FunctionBreakpoint[]
{
new FunctionBreakpoint
{
Name = "Write-Host",
}
}
}).ConfigureAwait(false);

var breakpoint = setBreakpointsResponse.Breakpoints.First();
Assert.True(breakpoint.Verified);

ConfigurationDoneResponse configDoneResponse = await PsesDebugAdapterClient.RequestConfigurationDone(new ConfigurationDoneArguments()).ConfigureAwait(false);
Assert.NotNull(configDoneResponse);

// At this point the script should be running so lets give it time
await Task.Delay(2000).ConfigureAwait(false);

var variablesResponse = await PsesDebugAdapterClient.RequestVariables(
new VariablesArguments
{
VariablesReference = 1
}).ConfigureAwait(false);

var form = variablesResponse.Variables.FirstOrDefault(v => v.Name == "$form");
Assert.NotNull(form);
Assert.Equal("System.Windows.Forms.Form, Text: ", form.Value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="OmniSharp.Extensions.LanguageClient" Version="0.19.2" />
<PackageReference Include="OmniSharp.Extensions.DebugAdapter.Client" Version="0.19.2" />
<PackageReference Include="OmniSharp.Extensions.LanguageClient" Version="0.19.3" />
<PackageReference Include="OmniSharp.Extensions.DebugAdapter.Client" Version="0.19.3" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="Xunit.SkippableFact" Version="1.4.13" />
Expand Down
41 changes: 16 additions & 25 deletions test/PowerShellEditorServices.Test/Debugging/DebugServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ public class DebugServiceTests : IDisposable
private AsyncQueue<SessionStateChangedEventArgs> sessionStateQueue =
new AsyncQueue<SessionStateChangedEventArgs>();

private ScriptFile GetDebugScript(string fileName)
{
return this.workspace.GetFile(
TestUtilities.NormalizePath(Path.Combine(
Path.GetDirectoryName(typeof(DebugServiceTests).Assembly.Location),
"../../../../PowerShellEditorServices.Test.Shared/Debugging",
fileName
)));
}

public DebugServiceTests()
{
var logger = NullLogger.Instance;
Expand All @@ -41,18 +51,9 @@ public DebugServiceTests()

this.workspace = new WorkspaceService(NullLoggerFactory.Instance);

// Load the test debug file
this.debugScriptFile =
this.workspace.GetFile(
TestUtilities.NormalizePath(Path.Combine(
Path.GetDirectoryName(typeof(DebugServiceTests).Assembly.Location),
"../../../../PowerShellEditorServices.Test.Shared/Debugging/VariableTest.ps1")));

this.variableScriptFile =
this.workspace.GetFile(
TestUtilities.NormalizePath(Path.Combine(
Path.GetDirectoryName(typeof(DebugServiceTests).Assembly.Location),
"../../../../PowerShellEditorServices.Test.Shared/Debugging/VariableTest.ps1")));
// Load the test debug files
this.debugScriptFile = GetDebugScript("DebugTest.ps1");
this.variableScriptFile = GetDebugScript("VariableTest.ps1");

this.debugService = new DebugService(
this.powerShellContext,
Expand All @@ -65,13 +66,6 @@ public DebugServiceTests()

this.debugService.DebuggerStopped += debugService_DebuggerStopped;
this.debugService.BreakpointUpdated += debugService_BreakpointUpdated;

// Load the test debug file
this.debugScriptFile =
this.workspace.GetFile(
TestUtilities.NormalizePath(Path.Combine(
Path.GetDirectoryName(typeof(DebugServiceTests).Assembly.Location),
"../../../../PowerShellEditorServices.Test.Shared/Debugging/DebugTest.ps1")));
}

async void powerShellContext_SessionStateChanged(object sender, SessionStateChangedEventArgs e)
Expand Down Expand Up @@ -123,11 +117,7 @@ public async Task DebuggerAcceptsScriptArgs(string[] args)
// The path is intentionally odd (some escaped chars but not all) because we are testing
// the internal path escaping mechanism - it should escape certains chars ([, ] and space) but
// it should not escape already escaped chars.
ScriptFile debugWithParamsFile =
this.workspace.GetFile(
TestUtilities.NormalizePath(Path.Combine(
Path.GetDirectoryName(typeof(DebugServiceTests).Assembly.Location),
"../../../../PowerShellEditorServices.Test.Shared/Debugging/Debug W&ith Params [Test].ps1")));
ScriptFile debugWithParamsFile = GetDebugScript("Debug W&ith Params [Test].ps1");

await this.debugService.SetLineBreakpointsAsync(
debugWithParamsFile,
Expand Down Expand Up @@ -889,7 +879,7 @@ await this.debugService.SetLineBreakpointsAsync(

var nullStringVar = variables.FirstOrDefault(v => v.Name == "$nullString");
Assert.NotNull(nullStringVar);
Assert.True("[NullString]".Equals(nullStringVar.ValueString));
Assert.Equal("[NullString]", nullStringVar.ValueString);
Assert.True(nullStringVar.IsExpandable);

// Abort script execution early and wait for completion
Expand Down Expand Up @@ -973,6 +963,7 @@ await this.debugService.SetLineBreakpointsAsync(

// Verifies fix for issue #86, $proc = Get-Process foo displays just the ETS property set
// and not all process properties.
[Trait("Category", "DebugService")]
[Fact]
public async Task DebuggerVariableProcessObjDisplaysCorrectly()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="Xunit.SkippableFact" Version="1.4.13" />
<PackageReference Include="OmniSharp.Extensions.LanguageServer" Version="0.19.2" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.4.0-beta.1.build3958" />
<PackageReference Include="OmniSharp.Extensions.LanguageServer" Version="0.19.3" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit 5bb5b8a

Please sign in to comment.