提交 6988e40f 编写于 作者: S Sam Harwell

Include XML test results in local test runs

Closes #47974
上级 637cb4c8
......@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
......@@ -10,7 +9,6 @@
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Threading.Tasks;
namespace RunTests
{
......@@ -33,12 +31,12 @@ internal struct AssemblyInfo
ExtraArguments = extraArguments;
}
internal AssemblyInfo(string assemblyPath, string targetFrameworkMoniker, string architecture, bool useHmtl)
internal AssemblyInfo(string assemblyPath, string targetFrameworkMoniker, string architecture, bool includeHtml)
{
AssemblyPath = assemblyPath;
DisplayName = Path.GetFileName(assemblyPath);
var suffix = useHmtl ? "html" : "xml";
var suffix = includeHtml ? "html" : "xml";
ResultsFileName = $"{DisplayName}_{targetFrameworkMoniker}_{architecture}.{suffix}";
ExtraArguments = string.Empty;
}
......@@ -91,23 +89,23 @@ private sealed class AssemblyInfoBuilder
private readonly StringBuilder _builder = new StringBuilder();
private readonly string _assemblyPath;
private readonly int _methodLimit;
private readonly bool _useHtml;
private readonly bool _includeHtml;
private readonly bool _hasEventListenerGuard;
private int _currentId;
private List<TypeInfo> _currentTypeInfoList = new List<TypeInfo>();
private AssemblyInfoBuilder(string assemblyPath, int methodLimit, bool useHtml, bool hasEventListenerGuard)
private AssemblyInfoBuilder(string assemblyPath, int methodLimit, bool includeHtml, bool hasEventListenerGuard)
{
_assemblyPath = assemblyPath;
_useHtml = useHtml;
_includeHtml = includeHtml;
_methodLimit = methodLimit;
_hasEventListenerGuard = hasEventListenerGuard;
}
internal static void Build(string assemblyPath, int methodLimit, bool useHtml, List<TypeInfo> typeInfoList, out List<Partition> partitionList, out List<AssemblyInfo> assemblyInfoList)
internal static void Build(string assemblyPath, int methodLimit, bool includeHtml, List<TypeInfo> typeInfoList, out List<Partition> partitionList, out List<AssemblyInfo> assemblyInfoList)
{
var hasEventListenerGuard = typeInfoList.Any(x => x.FullName == EventListenerGuardFullName);
var builder = new AssemblyInfoBuilder(assemblyPath, methodLimit, useHtml, hasEventListenerGuard);
var builder = new AssemblyInfoBuilder(assemblyPath, methodLimit, includeHtml, hasEventListenerGuard);
builder.Build(typeInfoList);
partitionList = builder._partitionList;
assemblyInfoList = builder._assemblyInfoList;
......@@ -169,7 +167,7 @@ private void FinishPartition()
{
var assemblyName = Path.GetFileName(_assemblyPath);
var displayName = $"{assemblyName}.{_currentId}";
var suffix = _useHtml ? "html" : "xml";
var suffix = _includeHtml ? "html" : "xml";
var resultsFileName = $"{assemblyName}.{_currentId}.{suffix}";
var assemblyInfo = new AssemblyInfo(
_assemblyPath,
......@@ -206,7 +204,7 @@ public IEnumerable<AssemblyInfo> Schedule(string assemblyPath, bool force = fals
var typeInfoList = GetTypeInfoList(assemblyPath);
var assemblyInfoList = new List<AssemblyInfo>();
var partitionList = new List<Partition>();
AssemblyInfoBuilder.Build(assemblyPath, _methodLimit, _options.UseHtml, typeInfoList, out partitionList, out assemblyInfoList);
AssemblyInfoBuilder.Build(assemblyPath, _methodLimit, _options.IncludeHtml, typeInfoList, out partitionList, out assemblyInfoList);
// If the scheduling didn't actually produce multiple partition then send back an unpartitioned
// representation.
......@@ -233,7 +231,7 @@ public IEnumerable<AssemblyInfo> Schedule(string assemblyPath, bool force = fals
public AssemblyInfo CreateAssemblyInfo(string assemblyPath)
{
return new AssemblyInfo(assemblyPath, _options.TargetFrameworkMoniker, _options.Test64 ? "x64" : "x86", _options.UseHtml);
return new AssemblyInfo(assemblyPath, _options.TargetFrameworkMoniker, _options.Test64 ? "x64" : "x86", _options.IncludeHtml);
}
private static List<TypeInfo> GetTypeInfoList(string assemblyPath)
......
......@@ -15,18 +15,18 @@ namespace RunTests
internal string OutputDirectory { get; }
internal string Trait { get; }
internal string NoTrait { get; }
internal bool UseHtml { get; }
internal bool IncludeHtml { get; }
internal bool Test64 { get; }
internal bool TestVsi { get; }
internal TestExecutionOptions(string xunitPath, ProcDumpInfo? procDumpInfo, string outputDirectory, string trait, string noTrait, bool useHtml, bool test64, bool testVsi)
internal TestExecutionOptions(string xunitPath, ProcDumpInfo? procDumpInfo, string outputDirectory, string trait, string noTrait, bool includeHtml, bool test64, bool testVsi)
{
XunitPath = xunitPath;
ProcDumpInfo = procDumpInfo;
OutputDirectory = outputDirectory;
Trait = trait;
NoTrait = noTrait;
UseHtml = useHtml;
IncludeHtml = includeHtml;
Test64 = test64;
TestVsi = testVsi;
}
......
......@@ -23,7 +23,7 @@ internal class Options
/// <summary>
/// Use HTML output files.
/// </summary>
public bool UseHtml { get; set; }
public bool IncludeHtml { get; set; }
/// <summary>
/// Use the 64 bit test runner.
......@@ -119,7 +119,7 @@ bool isOption(string argument, string optionName, out string value)
return false;
}
var opt = new Options { XunitPath = args[0], UseHtml = true, TestResultXmlOutputDirectory = Path.Combine(Directory.GetCurrentDirectory(), "TestResults") };
var opt = new Options { XunitPath = args[0], IncludeHtml = true, TestResultXmlOutputDirectory = Path.Combine(Directory.GetCurrentDirectory(), "TestResults") };
var index = 1;
var allGood = true;
while (index < args.Length)
......@@ -137,7 +137,7 @@ bool isOption(string argument, string optionName, out string value)
}
else if (comparer.Equals(current, "-xml"))
{
opt.UseHtml = false;
opt.IncludeHtml = false;
index++;
}
else if (isOption(current, "-tfm", out string targetFrameworkMoniker))
......
......@@ -32,11 +32,17 @@ public string GetCommandLineArguments(AssemblyInfo assemblyInfo)
{
var assemblyName = Path.GetFileName(assemblyInfo.AssemblyPath);
var resultsFilePath = GetResultsFilePath(assemblyInfo);
var xmlResultsFilePath = Path.ChangeExtension(resultsFilePath, ".xml");
var htmlResultsFilePath = Path.ChangeExtension(resultsFilePath, ".html");
var builder = new StringBuilder();
builder.AppendFormat(@"""{0}""", assemblyInfo.AssemblyPath);
builder.AppendFormat(@" {0}", assemblyInfo.ExtraArguments);
builder.AppendFormat(@" -{0} ""{1}""", Options.UseHtml ? "html" : "xml", resultsFilePath);
builder.AppendFormat($@" -xml ""{xmlResultsFilePath}""");
if (Options.IncludeHtml)
builder.AppendFormat($@" -html ""{htmlResultsFilePath}""");
builder.Append(" -noshadow -verbose");
if (!string.IsNullOrWhiteSpace(Options.Trait))
......@@ -70,7 +76,7 @@ public async Task<TestResult> RunTestAsync(AssemblyInfo assemblyInfo, Cancellati
var result = await RunTestAsyncInternal(assemblyInfo, retry: false, cancellationToken);
// For integration tests (TestVsi), we make one more attempt to re-run failed tests.
if (Options.TestVsi && !Options.UseHtml && !result.Succeeded)
if (Options.TestVsi && !Options.IncludeHtml && !result.Succeeded)
{
return await RunTestAsyncInternal(assemblyInfo, retry: true, cancellationToken);
}
......
......@@ -328,7 +328,7 @@ private static ProcessTestExecutor CreateTestExecutor(Options options)
outputDirectory: options.TestResultXmlOutputDirectory,
trait: options.Trait,
noTrait: options.NoTrait,
useHtml: options.UseHtml,
includeHtml: options.IncludeHtml,
test64: options.Test64,
testVsi: options.TestVsi);
return new ProcessTestExecutor(testExecutionOptions);
......
......@@ -175,7 +175,7 @@ private void PrintFailedTestResult(TestResult testResult)
}
// If the results are html, use Process.Start to open in the browser.
if (_options.UseHtml && !string.IsNullOrEmpty(testResult.ResultsFilePath))
if (_options.IncludeHtml && !string.IsNullOrEmpty(testResult.ResultsFilePath))
{
Process.Start(testResult.ResultsFilePath);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册