Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix server mode in playground #4243

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 3 additions & 2 deletions samples/Playground/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public static async Task<int> Main(string[] args)
{
// To attach to the children
Microsoft.Testing.TestInfrastructure.DebuggerUtility.AttachCurrentProcessToParentVSProcess();

ITestApplicationBuilder testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);

// Test MSTest
Expand All @@ -37,7 +38,7 @@ public static async Task<int> Main(string[] args)
// testApplicationBuilder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, _) => new DummyAdapter());

// Custom test host controller extension
testApplicationBuilder.TestHostControllers.AddProcessLifetimeHandler(s => new OutOfProc(s.GetMessageBus()));
// testApplicationBuilder.TestHostControllers.AddProcessLifetimeHandler(s => new OutOfProc(s.GetMessageBus()));

// Enable Trx
// testApplicationBuilder.AddTrxReportProvider();
Expand All @@ -50,7 +51,7 @@ public static async Task<int> Main(string[] args)
else
{
Environment.SetEnvironmentVariable("TESTSERVERMODE", "0");
using TestingPlatformClient client = await TestingPlatformClientFactory.StartAsServerAndConnectAsync(Environment.ProcessPath!, enableDiagnostic: true);
using TestingPlatformClient client = await TestingPlatformClientFactory.StartAsServerAndConnectToTheClientAsync(Environment.ProcessPath!);

await client.InitializeAsync();
List<TestNodeUpdate> testNodeUpdates = new();
Expand Down
80 changes: 0 additions & 80 deletions samples/Playground/ServerMode/TestingPlatformClientFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,86 +74,6 @@ public static async Task<TestingPlatformClient> StartAsServerAndConnectToTheClie
return new TestingPlatformClient(new(tcpClient.GetStream()), tcpClient, processHandler);
}

public static async Task<TestingPlatformClient> StartAsServerAndConnectAsync(string testApp, bool enableDiagnostic = false)
{
var environmentVariables = new Dictionary<string, string>(DefaultEnvironmentVariables);
foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables())
{
// Skip all unwanted environment variables.
string? key = entry.Key.ToString();
if (WellKnownEnvironmentVariables.ToSkipEnvironmentVariables.Contains(key, StringComparer.OrdinalIgnoreCase))
{
continue;
}

environmentVariables[key!] = entry.Value!.ToString()!;
}

// We expect to not fail for unhandled exception in server mode for IDE needs.
environmentVariables.Add("TESTINGPLATFORM_EXIT_PROCESS_ON_UNHANDLED_EXCEPTION", "0");

// To attach to the server on startup
// environmentVariables.Add(EnvironmentVariableConstants.TESTINGPLATFORM_LAUNCH_ATTACH_DEBUGGER, "1");
TaskCompletionSource<int> portFound = new();
ProcessConfiguration processConfig = new(testApp)
{
OnStandardOutput =
(_, output) =>
{
Match m = ParsePort().Match(output);
if (m.Success && int.TryParse(m.Groups[1].Value, out int port))
{
portFound.SetResult(port);
}

// Do not remove pls
// NotepadWindow.WriteLine($"[OnStandardOutput] {output}");
},

// Do not remove pls
// OnErrorOutput = (_, output) => NotepadWindow.WriteLine($"[OnErrorOutput] {output}"),
OnErrorOutput = (_, output) =>
{
if (!portFound.Task.IsCompleted)
{
try
{
portFound.SetException(new InvalidOperationException(output));
}
catch (InvalidOperationException)
{
// possible race
}
}
},
OnExit = (processHandle, exitCode) =>
{
if (exitCode != 0)
{
if (portFound.Task.Exception is null && !portFound.Task.IsCompleted)
{
portFound.SetException(new InvalidOperationException($"Port not found during parsing and process exited with code '{exitCode}'"));
}
}
},

// OnExit = (_, exitCode) => NotepadWindow.WriteLine($"[OnExit] Process exit code '{exitCode}'"),
Arguments = "--server --diagnostic --diagnostic-verbosity trace",
// Arguments = "--server",
EnvironmentVariables = environmentVariables,
};

IProcessHandle processHandler = ProcessFactory.Start(processConfig, cleanDefaultEnvironmentVariableIfCustomAreProvided: false);
await portFound.Task;

var tcpClient = new TcpClient();
using CancellationTokenSource cancellationTokenSource = new(TimeSpan.FromSeconds(90));
#pragma warning disable VSTHRD103 // Call async methods when in an async method
await tcpClient.ConnectAsync(new IPEndPoint(IPAddress.Loopback, portFound.Task.Result), cancellationTokenSource.Token);
#pragma warning restore VSTHRD103 // Call async methods when in an async method
return new TestingPlatformClient(new(tcpClient.GetStream()), tcpClient, processHandler, enableDiagnostic);
}

[GeneratedRegex(@"Starting server. Listening on port '(\d+)'")]
private static partial Regex ParsePort();
}
Expand Down
Loading