diff --git a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs
index d03ee27538..6964e5c01f 100644
--- a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs
+++ b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs
@@ -210,8 +210,18 @@ public static string PrepareArguments(string testAssembly, string? testAdapterPa
///
/// Arguments provided to vstest.console.exe
/// Environment variables to set to the started process.
- public void InvokeVsTest(string? arguments, Dictionary? environmentVariables = null)
+ /// When true, automatically adds --diag flag and attaches logs to test results on failure.
+ public void InvokeVsTest(string? arguments, Dictionary? environmentVariables = null, bool collectDiagnostics = true)
{
+ if (collectDiagnostics && !IsDiagAlreadyEnabled(arguments ?? ""))
+ {
+ var diagLogsDir = Path.Combine(TempDirectory.Path, "logs");
+ Directory.CreateDirectory(diagLogsDir);
+ arguments = string.Concat(arguments, GetDiagArg(diagLogsDir));
+ _attachments.Add(diagLogsDir);
+ Console.WriteLine($"Diagnostic logs directory: {diagLogsDir}");
+ }
+
var debugEnvironmentVariables = AddDebugEnvironmentVariables(environmentVariables);
ExecuteVsTestConsole(arguments, out _standardTestOutput, out _standardTestError, out _runnerExitCode, debugEnvironmentVariables);
FormatStandardOutCome();
@@ -223,7 +233,8 @@ public void InvokeVsTest(string? arguments, Dictionary? environ
/// Arguments provided to vstest.console.exe
/// Environment variables to set to the started process.
///
- public void InvokeDotnetTest(string arguments, Dictionary? environmentVariables = null, string? workingDirectory = null)
+ /// When true, automatically adds --diag flag and attaches logs to test results on failure.
+ public void InvokeDotnetTest(string arguments, Dictionary? environmentVariables = null, string? workingDirectory = null, bool collectDiagnostics = true)
{
string globalJsonPath = Path.Combine(workingDirectory!, "global.json");
if (workingDirectory is not null && !File.Exists(globalJsonPath))
@@ -272,6 +283,28 @@ public void InvokeDotnetTest(string arguments, Dictionary? envi
// https://github.com/dotnet/sdk/blob/main/src/Cli/dotnet/commands/dotnet-test/VSTestForwardingApp.cs#L30-L39
debugEnvironmentVariables["VSTEST_CONSOLE_PATH"] = vstestConsolePath;
+ if (collectDiagnostics && !IsDiagAlreadyEnabled(arguments))
+ {
+ var diagLogsDir = Path.Combine(TempDirectory.Path, "logs");
+ Directory.CreateDirectory(diagLogsDir);
+ var diagPath = Path.Combine(diagLogsDir, "log.txt");
+ var diagArg = " --diag " + diagPath.AddDoubleQuote();
+
+ // Insert --diag before the -- separator so dotnet test forwards it to vstest.console.
+ var separatorPos = arguments.IndexOf(" -- ");
+ if (separatorPos == -1)
+ {
+ arguments += diagArg;
+ }
+ else
+ {
+ arguments = arguments.Insert(separatorPos, diagArg);
+ }
+
+ _attachments.Add(diagLogsDir);
+ Console.WriteLine($"Diagnostic logs directory: {diagLogsDir}");
+ }
+
IntegrationTestBase.ExecutePatchedDotnet("test", arguments, out _standardTestOutput, out _standardTestError, out _runnerExitCode, debugEnvironmentVariables, workingDirectory);
FormatStandardOutCome();
}
@@ -284,14 +317,16 @@ public void InvokeDotnetTest(string arguments, Dictionary? envi
/// Dotnet Framework of test assembly.
/// Run settings for execution.
/// Environment variables to set to the started process.
+ /// When true, automatically adds --diag flag and attaches logs to test results on failure.
public void InvokeVsTestForExecution(string testAssembly,
string? testAdapterPath,
string framework,
string? runSettings = "",
- Dictionary? environmentVariables = null)
+ Dictionary? environmentVariables = null,
+ bool collectDiagnostics = true)
{
var arguments = PrepareArguments(testAssembly, testAdapterPath, runSettings, framework, _testEnvironment.InIsolationValue, resultsDirectory: TempDirectory.Path);
- InvokeVsTest(arguments, environmentVariables);
+ InvokeVsTest(arguments, environmentVariables, collectDiagnostics);
}
private Dictionary AddDebugEnvironmentVariables(Dictionary? environmentVariables)
@@ -1037,6 +1072,21 @@ protected string BuildMultipleAssemblyPath(params string[] assetNames)
return string.Join(" ", GetTestDlls(assetNames).Select(a => a.AddDoubleQuote()));
}
+ private static bool IsDiagAlreadyEnabled(string arguments)
+ {
+ // Check args for --diag, /diag, -diag (case-insensitive)
+ if (arguments.Contains("--diag", StringComparison.OrdinalIgnoreCase)
+ || arguments.Contains("/diag", StringComparison.OrdinalIgnoreCase)
+ || arguments.Contains("-diag", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+
+ // Check environment variable
+ var envDiag = Environment.GetEnvironmentVariable("VSTEST_DIAG");
+ return !StringUtils.IsNullOrEmpty(envDiag);
+ }
+
protected static string GetDiagArg(string rootDir)
=> " --diag:" + Path.Combine(rootDir, "log.txt");