Skip to content

Commit

Permalink
Correctly wait for completion of DelegatingXmlCreationSink (#906)
Browse files Browse the repository at this point in the history
With dotnet/runtime#62501 we were only waiting for completion of the DelegatingExecutionSummarySink, not the DelegatingXmlCreationSink.

Since DelegatingXmlCreationSink doesn't provide a callback when testing is done we need to add a wrapper execution sink that listens for the ITestAssemblyFinished message.

I also noticed we were using MemoryStream.ToArray() when sending the results which creates an additional copy that we can avoid.

Fixes #903
  • Loading branch information
akoeplinger authored Jun 14, 2022
1 parent a194f1a commit 5a55841
Showing 1 changed file with 33 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.DotNet.XHarness.Common;
Expand Down Expand Up @@ -56,10 +57,9 @@ public override async Task Run(IEnumerable<TestAssemblyInfo> testAssemblies)
Console.WriteLine($"Discovered: {assemblyFileName} (found {testCasesToRun.Count} of {discoverySink.TestCases.Count} test cases)");

var summaryTaskSource = new TaskCompletionSource<ExecutionSummary>();
var summarySink = new DelegatingExecutionSummarySink(testSink, () => false, (completed, summary) => summaryTaskSource.SetResult(summary));
var resultsXmlAssembly = new XElement("assembly");
var resultsSink = new DelegatingXmlCreationSink(summarySink, resultsXmlAssembly);

var resultsSink = new DelegatingXmlCreationSink(new DelegatingExecutionSummarySink(testSink), resultsXmlAssembly);
var completionSink = new CompletionCallbackExecutionSink(resultsSink, summary => summaryTaskSource.SetResult(summary));

if (Environment.GetEnvironmentVariable("XHARNESS_LOG_TEST_START") != null)
{
Expand All @@ -85,9 +85,10 @@ public override async Task Run(IEnumerable<TestAssemblyInfo> testAssemblies)
testSink.Execution.TestAssemblyStartingEvent += args => { Console.WriteLine($"Starting: {assemblyFileName}"); };
testSink.Execution.TestAssemblyFinishedEvent += args => { Console.WriteLine($"Finished: {assemblyFileName}"); };

controller.RunTests(testCasesToRun, resultsSink, testOptions);
controller.RunTests(testCasesToRun, completionSink, testOptions);

totalSummary = Combine(totalSummary, await summaryTaskSource.Task);

_assembliesElement.Add(resultsXmlAssembly);
}
TotalTests = totalSummary.Total;
Expand Down Expand Up @@ -119,13 +120,12 @@ public override void WriteResultsToFile(TextWriter writer, XmlResultJargon jargo
{
if (_oneLineResults)
{

using var ms = new MemoryStream();
_assembliesElement.Save(ms);
var bytes = ms.ToArray();
ms.TryGetBuffer(out var bytes);
var base64 = Convert.ToBase64String(bytes, Base64FormattingOptions.None);
Console.WriteLine($"STARTRESULTXML {bytes.Length} {base64} ENDRESULTXML");
Console.WriteLine($"Finished writing {bytes.Length} bytes of RESULTXML");
Console.WriteLine($"STARTRESULTXML {bytes.Count} {base64} ENDRESULTXML");
Console.WriteLine($"Finished writing {bytes.Count} bytes of RESULTXML");
}
else
{
Expand Down Expand Up @@ -174,3 +174,28 @@ public bool OnMessage(IMessageSinkMessage message)
return true;
}
}

internal class CompletionCallbackExecutionSink : global::Xunit.Sdk.LongLivedMarshalByRefObject, IExecutionSink
{
private readonly Action<ExecutionSummary> _completionCallback;
private readonly IExecutionSink _innerSink;

public ExecutionSummary ExecutionSummary => _innerSink.ExecutionSummary;

public ManualResetEvent Finished => _innerSink.Finished;

public CompletionCallbackExecutionSink(IExecutionSink innerSink, Action<ExecutionSummary> completionCallback)
{
_innerSink = innerSink;
_completionCallback = completionCallback;
}

public void Dispose() => _innerSink.Dispose();

public bool OnMessageWithTypes(IMessageSinkMessage message, HashSet<string> messageTypes)
{
var result = _innerSink.OnMessageWithTypes(message, messageTypes);
message.Dispatch<ITestAssemblyFinished>(messageTypes, args => _completionCallback(ExecutionSummary));
return result;
}
}

0 comments on commit 5a55841

Please sign in to comment.