Skip to content

Commit

Permalink
Enable test timeout dump collection (#44730)
Browse files Browse the repository at this point in the history
Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
Co-authored-by: Daniel Plaisted <daplaist@microsoft.com>
  • Loading branch information
3 people authored Nov 22, 2024
1 parent e2b4f9e commit aef12ba
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 38 deletions.
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
24 changes: 22 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,31 @@ 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

// The current process should be dotnet in most normal scenarios except when dotnet.dll is loaded in a custom host like the testhost
if (!Path.GetFileNameWithoutExtension(processPath).Equals("dotnet", 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

0 comments on commit aef12ba

Please sign in to comment.