private RemoteTestExecution StartTraceeProcess(string loggerCategory, string transportName = null) { _outputHelper.WriteLine("Starting tracee."); string exePath = CommonHelper.GetTraceePathWithArgs("EventPipeTracee", targetFramework: "net5.0"); return(RemoteTestExecution.StartProcess(exePath + " " + loggerCategory, _outputHelper, transportName)); }
public static RemoteTestExecution StartRemoteProcess(Func <string, int> testEntry, string loggerCategory, ITestOutputHelper outputHelper) { var options = new RemoteInvokeOptions() { Start = true, ExpectedExitCode = 0, CheckExitCode = true, StartInfo = new ProcessStartInfo { RedirectStandardError = true, RedirectStandardOutput = true, RedirectStandardInput = true }, }; var testExecution = new RemoteTestExecution(); //Note lambdas may not work here since closures cannot be properly serialized across process boundaries. testExecution.RemoteProcess = RemoteExecutor.Invoke(testEntry, loggerCategory, options); try { Task <string> stdOutputTask = testExecution.RemoteProcess.Process.StandardOutput.ReadToEndAsync(); Task <string> stdErrorTask = testExecution.RemoteProcess.Process.StandardError.ReadToEndAsync(); Task.Run(async() => { try { string result = await stdOutputTask; outputHelper.WriteLine("Stdout:"); if (result != null) { outputHelper.WriteLine(result); } result = await stdErrorTask; outputHelper.WriteLine("Stderr:"); if (result != null) { outputHelper.WriteLine(result); } } catch (Exception e) { outputHelper.WriteLine(e.ToString()); throw; } }); } catch (ObjectDisposedException) { outputHelper.WriteLine("Failed to collect remote process's output"); } return(testExecution); }
public async Task TestDiagnosticsEventPipeProcessorLogs() { var outputStream = new MemoryStream(); await using (var testExecution = RemoteTestExecution.StartRemoteProcess("LoggerRemoteTest", _output)) { //TestRunner should account for start delay to make sure that the diagnostic pipe is available. var loggerFactory = new LoggerFactory(new[] { new StreamingLoggerProvider(outputStream, LogFormat.Json) }); DiagnosticsEventPipeProcessor diagnosticsEventPipeProcessor = new DiagnosticsEventPipeProcessor( PipeMode.Logs, loggerFactory, Enumerable.Empty <IMetricsLogger>()); var processingTask = diagnosticsEventPipeProcessor.Process(testExecution.TestRunner.Pid, TimeSpan.FromSeconds(10), CancellationToken.None); //Add a small delay to make sure diagnostic processor had a chance to initialize await Task.Delay(1000); //Send signal to proceed with event collection testExecution.Start(); await processingTask; await diagnosticsEventPipeProcessor.DisposeAsync(); loggerFactory.Dispose(); } outputStream.Position = 0L; Assert.True(outputStream.Length > 0, "No data written by logging process."); using var reader = new StreamReader(outputStream); string firstMessage = reader.ReadLine(); Assert.NotNull(firstMessage); LoggerTestResult result = JsonSerializer.Deserialize <LoggerTestResult>(firstMessage); Assert.Equal("Some warning message with 6", result.Message); Assert.Equal("LoggerRemoteTest", result.Category); Assert.Equal("Warning", result.LogLevel); Assert.Equal("0", result.EventId); Validate(result.Scopes, ("BoolValue", "true"), ("StringValue", "test"), ("IntValue", "5")); Validate(result.Arguments, ("arg", "6")); string secondMessage = reader.ReadLine(); Assert.NotNull(secondMessage); result = JsonSerializer.Deserialize <LoggerTestResult>(secondMessage); Assert.Equal("Another message", result.Message); Assert.Equal("LoggerRemoteTest", result.Category); Assert.Equal("Warning", result.LogLevel); Assert.Equal("0", result.EventId); Assert.Equal(0, result.Scopes.Count); //We are expecting only the original format Assert.Equal(1, result.Arguments.Count); }