Skip to content

Enable test timeout dump collection #44730

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

Merged
merged 17 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from 14 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
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,7 @@ public ForwardingAppImplementation WithEnvironmentVariable(string name, string v
return this;
}

private string GetHostExeName()
{
// Should instead make this a full path to dotnet
return Environment.ProcessPath;
}
private string GetHostExeName() => new Muxer().MuxerPath;
}
}

Expand Down
25 changes: 23 additions & 2 deletions src/Cli/Microsoft.DotNet.Cli.Utils/Muxer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,32 @@ public string MuxerPath

public Muxer()
{
// Best-effort search for muxer.
// SDK sets DOTNET_HOST_PATH as absolute path to current dotnet executable
#if NET6_0_OR_GREATER
_muxerPath = Environment.ProcessPath;
string processPath = Environment.ProcessPath;
#else
_muxerPath = Process.GetCurrentProcess().MainModule.FileName;
string processPath = Process.GetCurrentProcess().MainModule.FileName;
#endif
string hostName = "dotnet" + Constants.ExeSuffix;

// The current process should be dotnet in most normal scenarios except when dotnet.dll is loaded in a custom host like the testhost
if (!processPath.EndsWith(hostName, StringComparison.OrdinalIgnoreCase))
{
// SDK sets DOTNET_HOST_PATH as absolute path to current dotnet executable
processPath = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH");
if (processPath is null)
{
// fallback to DOTNET_ROOT which typically holds some dotnet executable
var root = Environment.GetEnvironmentVariable("DOTNET_ROOT");
if (root is not null)
{
processPath = Path.Combine(root, $"dotnet{Constants.ExeSuffix}");
}
}
}

_muxerPath = processPath;
}

public static string GetDataFromAppDomain(string propertyName)
Expand Down
2 changes: 1 addition & 1 deletion test/ArgumentForwarding.Tests/ArgumentForwardingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ private string[] EscapeAndEvaluateArgumentString(string[] rawEvaluatedArgument)

Console.WriteLine($"STDERR: {commandResult.StdErr}");

commandResult.ExitCode.Should().Be(0);
commandResult.ExitCode.Should().Be(0, $"STDOUT: {commandResult.StdOut} STDERR: {commandResult.StdErr}");

return ParseReflectorOutput(commandResult.StdOut);
}
Expand Down
20 changes: 6 additions & 14 deletions test/HelixTasks/AssemblyScheduler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,18 @@ private sealed class AssemblyInfoBuilder
private readonly StringBuilder _builder = new();
private readonly string _assemblyPath;
private readonly int _methodLimit;
private readonly bool _netFramework;
private int _currentId;
private List<TypeInfo> _currentTypeInfoList = new();

private AssemblyInfoBuilder(string assemblyPath, int methodLimit, bool netFramework = false)
private AssemblyInfoBuilder(string assemblyPath, int methodLimit)
{
_assemblyPath = assemblyPath;
_methodLimit = methodLimit;
_netFramework = netFramework;
}

internal static void Build(string assemblyPath, int methodLimit, List<TypeInfo> typeInfoList, out List<Partition> partitionList, out List<AssemblyPartitionInfo> assemblyInfoList, bool netFramework = false)
{
var builder = new AssemblyInfoBuilder(assemblyPath, methodLimit, netFramework);
var builder = new AssemblyInfoBuilder(assemblyPath, methodLimit);
builder.Build(typeInfoList);
partitionList = builder._partitionList;
assemblyInfoList = builder._assemblyInfoList;
Expand All @@ -95,19 +93,13 @@ private void Build(List<TypeInfo> typeInfoList)
foreach (var typeInfo in typeInfoList)
{
_currentTypeInfoList.Add(typeInfo);
if (_netFramework)
{
if (_builder.Length > 0)
{
_builder.Append("|");
}
_builder.Append($@"{typeInfo.FullName}");

}
else
if (_builder.Length > 0)
{
_builder.Append($@"-class ""{typeInfo.FullName}"" ");
_builder.Append("|");
}
_builder.Append($@"{typeInfo.FullName}");

CheckForPartitionLimit(done: false);
}

Expand Down
23 changes: 7 additions & 16 deletions test/HelixTasks/SDKCustomCreateXUnitWorkItemsWithTestExclusion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,9 @@ private async Task<List<ITaskItem>> PrepareWorkItem(ITaskItem xunitProject)
// These tests have to be executed slightly differently and we give them a different Identity so ADO can tell them apart
var runtimeTargetFrameworkParsed = NuGetFramework.Parse(runtimeTargetFramework);
var testIdentityDifferentiator = "";
bool netFramework = false;
if (runtimeTargetFrameworkParsed.Framework == ".NETFramework")
{
testIdentityDifferentiator = ".netfx";
netFramework = true;
}
else if (runtimeTargetFrameworkParsed.Framework != ".NETCoreApp")
{
Expand All @@ -134,9 +132,9 @@ private async Task<List<ITaskItem>> PrepareWorkItem(ITaskItem xunitProject)

// On mac due to https://github.com/dotnet/sdk/issues/3923, we run against workitem directory
// but on Windows, if we running against working item diretory, we would hit long path.
string testExecutionDirectory = netFramework ? "-e DOTNET_SDK_TEST_EXECUTION_DIRECTORY=%TestExecutionDirectory%" : IsPosixShell ? "-testExecutionDirectory $TestExecutionDirectory" : "-testExecutionDirectory %TestExecutionDirectory%";
string testExecutionDirectory = IsPosixShell ? "-e DOTNET_SDK_TEST_EXECUTION_DIRECTORY=$TestExecutionDirectory" : "-e DOTNET_SDK_TEST_EXECUTION_DIRECTORY=%TestExecutionDirectory%";

string msbuildAdditionalSdkResolverFolder = netFramework ? "-e DOTNET_SDK_TEST_MSBUILDSDKRESOLVER_FOLDER=%HELIX_CORRELATION_PAYLOAD%\\r" : IsPosixShell ? "" : "-msbuildAdditionalSdkResolverFolder %HELIX_CORRELATION_PAYLOAD%\\r";
string msbuildAdditionalSdkResolverFolder = IsPosixShell ? "" : "-e DOTNET_SDK_TEST_MSBUILDSDKRESOLVER_FOLDER=%HELIX_CORRELATION_PAYLOAD%\\r";

if (ExcludeAdditionalParameters.Equals("true"))
{
Expand All @@ -145,23 +143,16 @@ private async Task<List<ITaskItem>> PrepareWorkItem(ITaskItem xunitProject)
}

var scheduler = new AssemblyScheduler(methodLimit: !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TestFullMSBuild")) ? 32 : 16);
var assemblyPartitionInfos = scheduler.Schedule(targetPath, netFramework: netFramework);
var assemblyPartitionInfos = scheduler.Schedule(targetPath);

var partitionedWorkItem = new List<ITaskItem>();
foreach (var assemblyPartitionInfo in assemblyPartitionInfos)
{
string command;
if (netFramework)
{
var testFilter = string.IsNullOrEmpty(assemblyPartitionInfo.ClassListArgumentString) ? "" : $"--filter \"{assemblyPartitionInfo.ClassListArgumentString}\"";
command = $"{driver} test {assemblyName} -e HELIX_WORK_ITEM_TIMEOUT={timeout} {testExecutionDirectory} {msbuildAdditionalSdkResolverFolder} " +
$"{(XUnitArguments != null ? " " + XUnitArguments : "")} --results-directory .\\ --logger trx {testFilter}";
}
else
{
command = $"{driver} exec {assemblyName} -e HELIX_WORK_ITEM_TIMEOUT={timeout} {testExecutionDirectory} {msbuildAdditionalSdkResolverFolder} " +
$"{(XUnitArguments != null ? " " + XUnitArguments : "")} -xml testResults.xml {assemblyPartitionInfo.ClassListArgumentString} {arguments}";
}

var testFilter = string.IsNullOrEmpty(assemblyPartitionInfo.ClassListArgumentString) ? "" : $"--filter \"{assemblyPartitionInfo.ClassListArgumentString}\"";
command = $"{driver} test {assemblyName} -e HELIX_WORK_ITEM_TIMEOUT={timeout} {testExecutionDirectory} {msbuildAdditionalSdkResolverFolder} " +
$"{(XUnitArguments != null ? " " + XUnitArguments : "")} --results-directory .{Path.DirectorySeparatorChar} --logger trx --blame-hang --blame-hang-timeout 30m {testFilter} -- {arguments}";

Log.LogMessage($"Creating work item with properties Identity: {assemblyName}, PayloadDirectory: {publishDirectory}, Command: {command}");

Expand Down