Skip to content

Commit 8fc29af

Browse files
kotlarmilosCopilot
andauthored
Enable NativeAOT support for iOS test runner (#1554)
Make ThreadlessXunitTestRunner platform-generic so it can be used on iOS/tvOS/Mac Catalyst in addition to WASM. The runner uses reflection-based test discovery (ThreadlessXunitDiscoverer) which is NativeAOT-compatible, unlike XUnitTestRunner which depends on XunitFrontController for dynamic assembly loading. Changes: - ThreadlessXunitTestRunner: make ResultsFileName settable, refactor WriteResultsToFile to support file-based XML output on non-browser platforms while preserving existing WASM behavior - iOSApplicationEntryPoint: detect NativeAOT via RuntimeFeature.IsDynamicCodeSupported and automatically use ThreadlessXunitTestRunner when dynamic code is not available Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ea007a3 commit 8fc29af

2 files changed

Lines changed: 43 additions & 6 deletions

File tree

src/Microsoft.DotNet.XHarness.TestRunners.Xunit/ThreadlessXunitTestRunner.cs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.IO;
99
using System.Linq;
1010
using System.Threading.Tasks;
11+
using System.Xml;
1112
using System.Xml.Linq;
1213
using Microsoft.DotNet.XHarness.Common;
1314
using Microsoft.DotNet.XHarness.TestRunners.Common;
@@ -24,7 +25,8 @@ public ThreadlessXunitTestRunner(LogWriter logger) : base(logger)
2425
ShowFailureInfos = false;
2526
}
2627

27-
protected override string ResultsFileName { get => string.Empty; set => throw new InvalidOperationException("This runner outputs its results to stdout."); }
28+
private string _resultsFileName = "TestResults.xUnit.xml";
29+
protected override string ResultsFileName { get => _resultsFileName; set => _resultsFileName = value; }
2830

2931
private XElement? _assembliesElement;
3032

@@ -121,14 +123,41 @@ private ExecutionSummary Combine(ExecutionSummary aggregateSummary, ExecutionSum
121123

122124
public override async Task<string> WriteResultsToFile(XmlResultJargon xmlResultJargon)
123125
{
124-
Debug.Assert(xmlResultJargon == XmlResultJargon.xUnit);
125-
await WriteResultsToFile(Console.Out, xmlResultJargon);
126-
return "";
126+
if (_assembliesElement is null)
127+
return string.Empty;
128+
129+
if (OperatingSystem.IsBrowser())
130+
{
131+
Debug.Assert(xmlResultJargon == XmlResultJargon.xUnit);
132+
await WriteResultsToFile(Console.Out, xmlResultJargon);
133+
return "";
134+
}
135+
136+
string outputFilePath = GetResultsFilePath();
137+
var settings = new XmlWriterSettings { Indent = true };
138+
using (var xmlWriter = XmlWriter.Create(outputFilePath, settings))
139+
{
140+
_assembliesElement.Save(xmlWriter);
141+
}
142+
143+
return outputFilePath;
127144
}
128145

129-
public override async Task WriteResultsToFile(TextWriter writer, XmlResultJargon jargon)
146+
public override Task WriteResultsToFile(TextWriter writer, XmlResultJargon jargon)
130147
{
131-
await WasmXmlResultWriter.WriteResultsToFile(ConsumeAssembliesElement());
148+
if (_assembliesElement is null)
149+
return Task.CompletedTask;
150+
151+
if (OperatingSystem.IsBrowser())
152+
return WasmXmlResultWriter.WriteResultsToFile(ConsumeAssembliesElement());
153+
154+
var settings = new XmlWriterSettings { Indent = true };
155+
using (var xmlWriter = XmlWriter.Create(writer, settings))
156+
{
157+
_assembliesElement.Save(xmlWriter);
158+
}
159+
160+
return Task.CompletedTask;
132161
}
133162
}
134163

src/Microsoft.DotNet.XHarness.TestRunners.Xunit/iOSApplicationEntryPoint.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Runtime.CompilerServices;
56
using Microsoft.DotNet.XHarness.TestRunners.Common;
67

78
#nullable enable
@@ -11,6 +12,13 @@ public abstract class iOSApplicationEntryPoint : iOSApplicationEntryPointBase
1112
{
1213
protected override TestRunner GetTestRunner(LogWriter logWriter)
1314
{
15+
if (!RuntimeFeature.IsDynamicCodeSupported)
16+
{
17+
var threadlessRunner = new ThreadlessXunitTestRunner(logWriter);
18+
ConfigureRunnerFilters(threadlessRunner, ApplicationOptions.Current);
19+
return threadlessRunner;
20+
}
21+
1422
var runner = new XUnitTestRunner(logWriter) { MaxParallelThreads = MaxParallelThreads };
1523
ConfigureRunnerFilters(runner, ApplicationOptions.Current);
1624
return runner;

0 commit comments

Comments
 (0)