Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
406e49b
dump using dotnet client
nohwnd Apr 14, 2020
1f0110f
slashes
nohwnd Apr 15, 2020
daedd29
Update version
nohwnd Apr 15, 2020
da4af02
Add dumping on dotnet windows
nohwnd Apr 15, 2020
ee6bf5b
Merge branch 'blame-datacollector' of https://github.com/nohwnd/vstes…
nohwnd Apr 15, 2020
3a36f8e
Merge branch 'master' of https://github.com/microsoft/vstest into bla…
nohwnd Apr 15, 2020
cbf6a16
Dump via api on windows
nohwnd Apr 15, 2020
49683f2
Dumping across platforms
nohwnd Apr 16, 2020
3f34922
Merge branch 'master' into blame-datacollector
nohwnd Apr 17, 2020
b910dd2
Add generating lock files and lock files
nohwnd Apr 17, 2020
7358b4f
Merge branch 'verify-nugets' into blame-datacollector
nohwnd Apr 17, 2020
a29606a
revert merge
nohwnd Apr 17, 2020
30bb98b
Up the number of files
nohwnd Apr 17, 2020
ad261a9
Add option for test timeout from the commandline, some logging, and g…
nohwnd Apr 22, 2020
529cc09
update
nohwnd Apr 23, 2020
6b0326d
try it on multiple
nohwnd Apr 24, 2020
474ef16
Partially revert blame
nohwnd Apr 27, 2020
10e0a60
Prodump conditions
nohwnd May 6, 2020
ea8333e
Update data collector to net472 and update the way we crash dump
nohwnd May 12, 2020
657bf3a
Path fix for crash dump
nohwnd May 12, 2020
ed82f47
Differentiate crashdump and hangdump
nohwnd May 13, 2020
aed6ce1
Revert unneeded changes
nohwnd May 13, 2020
3c8dccb
Style issues
nohwnd May 13, 2020
f3e24f2
Try fix unit tests
nohwnd May 14, 2020
ea79ab2
Revert removing env var
nohwnd May 14, 2020
f2314e5
Skip linux build
nohwnd May 14, 2020
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
20 changes: 11 additions & 9 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,15 @@ jobs:
testResultsFormat: VSTest
testResultsFiles: '**\*.trx'
condition: succeededOrFailed()

- job: Linux
pool:
vmImage: 'ubuntu-16.04'
variables:
buildConfiguration: 'Release'
steps:
- script: ./build.sh -c $(buildConfiguration)
displayName: './build.sh -c $(buildConfiguration)'

# Linux build does not work when we mix runtimes and
# we don't use the results to do anything, skipping it for now
# - job: Linux
# pool:
# vmImage: 'ubuntu-16.04'
# variables:
# buildConfiguration: 'Release'
# steps:
# - script: ./build.sh -c $(buildConfiguration)
# displayName: './build.sh -c $(buildConfiguration)'

17 changes: 14 additions & 3 deletions scripts/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ Write-Verbose "Setup build configuration."
$TPB_Solution = "TestPlatform.sln"
$TPB_TestAssets_Solution = Join-Path $env:TP_ROOT_DIR "test\TestAssets\TestAssets.sln"
$TPB_TargetFramework = "net451"
$TPB_TargetFramework472 = "net472"
$TPB_TargetFrameworkCore20 = "netcoreapp2.1"
$TPB_TargetFrameworkUap = "uap10.0"
$TPB_TargetFrameworkNS2_0 = "netstandard2.0"
Expand Down Expand Up @@ -321,7 +322,7 @@ function Publish-Package
Publish-PackageInternal $settingsMigratorProject $TPB_TargetFramework $fullCLRPackageDir

Write-Log "Package: Publish src\datacollector\datacollector.csproj"
Publish-PackageInternal $dataCollectorProject $TPB_TargetFramework $fullCLRPackageDir
Publish-PackageInternal $dataCollectorProject $TPB_TargetFramework472 $fullCLRPackageDir
Publish-PackageInternal $dataCollectorProject $TPB_TargetFrameworkCore20 $coreCLR20PackageDir

# Publish testhost
Expand Down Expand Up @@ -351,7 +352,7 @@ function Publish-Package
Set-ScriptFailedOnError

# Copy over the Full CLR built datacollector package assemblies to the Core CLR package folder along with testhost
Publish-PackageInternal $dataCollectorProject $TPB_TargetFramework $fullDestDir
Publish-PackageInternal $dataCollectorProject $TPB_TargetFramework472 $fullDestDir

New-Item -ItemType directory -Path $fullCLRPackageDir -Force | Out-Null
Copy-Item $testhostFullPackageDir\* $fullCLRPackageDir -Force -recurse
Expand Down Expand Up @@ -405,12 +406,22 @@ function Publish-Package
# Copy Blame Datacollector to Extensions folder.
$TPB_TargetFrameworkStandard = "netstandard2.0"
$blameDataCollector = Join-Path $env:TP_ROOT_DIR "src\Microsoft.TestPlatform.Extensions.BlameDataCollector\bin\$TPB_Configuration"
$blameDataCollectorNetFull = Join-Path $blameDataCollector $TPB_TargetFramework
$blameDataCollectorNetFull = Join-Path $blameDataCollector $TPB_TargetFramework472
$blameDataCollectorNetStandard = Join-Path $blameDataCollector $TPB_TargetFrameworkStandard
Copy-Item $blameDataCollectorNetFull\Microsoft.TestPlatform.Extensions.BlameDataCollector.dll $fullCLRExtensionsDir -Force
Copy-Item $blameDataCollectorNetFull\Microsoft.TestPlatform.Extensions.BlameDataCollector.pdb $fullCLRExtensionsDir -Force
Copy-Item $blameDataCollectorNetStandard\Microsoft.TestPlatform.Extensions.BlameDataCollector.dll $coreCLRExtensionsDir -Force
Copy-Item $blameDataCollectorNetStandard\Microsoft.TestPlatform.Extensions.BlameDataCollector.pdb $coreCLRExtensionsDir -Force
# we use this to dump processes on netcore
Copy-Item $blameDataCollectorNetStandard\Microsoft.Diagnostics.NETCore.Client.dll $coreCLRExtensionsDir -Force

# $null = New-Item -Force "$fullCLRExtensionsDir\procdump" -ItemType Directory
# $null = New-Item -Force "$coreCLRExtensionsDir\procdump" -ItemType Directory
# Copy-Item $blameDataCollectorNetFull\procdump.exe $fullCLRExtensionsDir\procdump -Force
# Copy-Item $blameDataCollectorNetFull\procdump64.exe $fullCLRExtensionsDir\procdump -Force
# Copy-Item $blameDataCollectorNetStandard\procdump.exe $coreCLRExtensionsDir\procdump -Force
# Copy-Item $blameDataCollectorNetStandard\procdump64.exe $coreCLRExtensionsDir\procdump -Force
# Copy-Item $blameDataCollectorNetStandard\procdump $coreCLRExtensionsDir\procdump -Force

# Copy blame data collector resource dlls
if($TPB_LocalizedBuild) {
Expand Down
8 changes: 4 additions & 4 deletions scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ done
#
TP_ROOT_DIR=$(cd "$(dirname "$0")"; pwd -P)
TP_TOOLS_DIR="$TP_ROOT_DIR/tools"
TP_DOTNET_DIR="${DOTNET_CORE_SDK_DIR:-${TP_TOOLS_DIR}/dotnet}"
TP_DOTNET_DIR="${DOTNET_CORE_SDK_DIR:-${TP_TOOLS_DIR}/dotnet-linux}"
TP_PACKAGES_DIR="${NUGET_PACKAGES:-${TP_ROOT_DIR}/packages}"
TP_OUT_DIR="$TP_ROOT_DIR/artifacts"
TP_PACKAGE_PROJ_DIR="$TP_ROOT_DIR/src/package/package"
Expand Down Expand Up @@ -186,12 +186,12 @@ function install_cli()
chmod u+x $install_script

log "install_cli: Get the latest dotnet cli toolset..."
$install_script --install-dir "$TP_TOOLS_DIR/dotnet" --no-path --channel "master" --version $DOTNET_CLI_VERSION
$install_script --install-dir "$TP_DOTNET_DIR" --no-path --channel "master" --version $DOTNET_CLI_VERSION

# Get netcoreapp1.1 shared components
$install_script --install-dir "$TP_TOOLS_DIR/dotnet" --no-path --channel "release/2.1.0" --version "2.1.0" --shared-runtime
$install_script --install-dir "$TP_DOTNET_DIR" --no-path --channel "release/2.1.0" --version "2.1.0" --runtime dotnet
#log "install_cli: Get shared components which is compatible with dotnet cli version $DOTNET_CLI_VERSION..."
#$install_script --install-dir "$TP_TOOLS_DIR/dotnet" --no-path --channel "master" --version $DOTNET_RUNTIME_VERSION --shared-runtime
#$install_script --install-dir "$TP_DOTNET_DIR" --no-path --channel "master" --version $DOTNET_RUNTIME_VERSION --runtime dotnet
fi

local dotnet_path=$(_get_dotnet_path)
Expand Down
2 changes: 1 addition & 1 deletion scripts/verify-nupkgs.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function Verify-Nuget-Packages($packageDirectory)
"Microsoft.NET.Test.Sdk" = 13;
"Microsoft.TestPlatform" = 437;
"Microsoft.TestPlatform.Build" = 19;
"Microsoft.TestPlatform.CLI" = 317;
"Microsoft.TestPlatform.CLI" = 318;
"Microsoft.TestPlatform.Extensions.TrxLogger" = 33;
"Microsoft.TestPlatform.ObjectModel" = 62;
"Microsoft.TestPlatform.Portable" = 502;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Microsoft.TestPlatform.Extensions.BlameDataCollector
using System.Xml;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection;
using Microsoft.VisualStudio.TestPlatform.Utilities;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces;

Expand Down Expand Up @@ -45,6 +46,8 @@ public class BlameCollector : DataCollector, ITestExecutionEnvironmentSpecifier
private IInactivityTimer inactivityTimer;
private TimeSpan inactivityTimespan = TimeSpan.FromMinutes(DefaultInactivityTimeInMinutes);
private int testHostProcessId;
private bool dumpWasCollectedByHangDumper;
private string targetFramework;

/// <summary>
/// Initializes a new instance of the <see cref="BlameCollector"/> class.
Expand All @@ -62,7 +65,7 @@ public BlameCollector()
/// BlameReaderWriter instance.
/// </param>
/// <param name="processDumpUtility">
/// ProcessDumpUtility instance.
/// IProcessDumpUtility instance.
/// </param>
/// <param name="inactivityTimer">
/// InactivityTimer instance.
Expand Down Expand Up @@ -138,6 +141,12 @@ public override void Initialize(
{
this.ValidateAndAddHangBasedProcessDumpParameters(collectHangBasedDumpNode);
}

var tfm = this.configurationElement[Constants.TargetFramework]?.InnerText;
if (!string.IsNullOrWhiteSpace(tfm))
{
this.targetFramework = tfm;
}
}

this.attachmentGuid = Guid.NewGuid().ToString().Replace("-", string.Empty);
Expand All @@ -157,8 +166,10 @@ public override void Initialize(
/// </summary>
private void CollectDumpAndAbortTesthost()
{
EqtTrace.Info(string.Format(CultureInfo.CurrentUICulture, Resources.Resources.InactivityTimeout, (int)this.inactivityTimespan.TotalMinutes));
this.inactivityTimerAlreadyFired = true;
var message = string.Format(CultureInfo.CurrentUICulture, Resources.Resources.InactivityTimeout, (int)this.inactivityTimespan.TotalMinutes);
EqtTrace.Warning(message);
this.logger.LogWarning(this.context.SessionDataCollectionContext, message);

try
{
Expand All @@ -170,27 +181,28 @@ private void CollectDumpAndAbortTesthost()
EqtTrace.Verbose("Inactivity timer is already disposed.");
}

if (this.collectProcessDumpOnTrigger)
{
// Detach procdump from the testhost process to prevent testhost process from crashing
// if/when we try to kill the existing proc dump process.
this.processDumpUtility.DetachFromTargetProcess(this.testHostProcessId);
}

try
{
this.processDumpUtility.StartHangBasedProcessDump(this.testHostProcessId, this.attachmentGuid, this.GetResultsDirectory(), this.processFullDumpEnabled);
this.processDumpUtility.StartHangBasedProcessDump(this.testHostProcessId, this.attachmentGuid, this.GetTempDirectory(), this.processFullDumpEnabled, this.targetFramework);
}
catch (Exception ex)
{
EqtTrace.Error($"BlameCollector.CollectDumpAndAbortTesthost: Failed with error {ex}");
ConsoleOutput.Instance.Error(true, $"Blame: Creating hang dump failed with error {ex}.");
}

if (this.collectProcessDumpOnTrigger)
{
// Detach procdump from the testhost process to prevent testhost process from crashing
// if/when we try to kill the existing proc dump process.
this.processDumpUtility.DetachFromTargetProcess(this.testHostProcessId);
}

try
{
var dumpFile = this.processDumpUtility.GetDumpFile();
if (!string.IsNullOrEmpty(dumpFile))
{
this.dumpWasCollectedByHangDumper = true;
var fileTransferInformation = new FileTransferInformation(this.context.SessionDataCollectionContext, dumpFile, true, this.fileHelper);
this.dataCollectionSink.SendFileAsync(fileTransferInformation);
}
Expand All @@ -207,7 +219,17 @@ private void CollectDumpAndAbortTesthost()

try
{
Process.GetProcessById(this.testHostProcessId).Kill();
var p = Process.GetProcessById(this.testHostProcessId);
try
{
if (!p.HasExited)
{
p.Kill();
}
}
catch (InvalidOperationException)
{
}
}
catch (Exception ex)
{
Expand Down Expand Up @@ -274,7 +296,7 @@ private void ValidateAndAddHangBasedProcessDumpParameters(XmlElement collectDump

break;

case XmlAttribute attribute when string.Equals(attribute.Name, Constants.DumpTypeKey, StringComparison.OrdinalIgnoreCase):
case XmlAttribute attribute when string.Equals(attribute.Name, Constants.HangDumpTypeKey, StringComparison.OrdinalIgnoreCase):

if (string.Equals(attribute.Value, Constants.FullConfigurationValue, StringComparison.OrdinalIgnoreCase) || string.Equals(attribute.Value, Constants.MiniConfigurationValue, StringComparison.OrdinalIgnoreCase))
{
Expand Down Expand Up @@ -365,7 +387,8 @@ private void SessionEndedHandler(object sender, SessionEndEventArgs args)
// And send the attachment
if (this.testStartCount > this.testEndCount)
{
var filepath = Path.Combine(this.GetResultsDirectory(), Constants.AttachmentFileName + "_" + this.attachmentGuid);
var filepath = Path.Combine(this.GetTempDirectory(), Constants.AttachmentFileName + "_" + this.attachmentGuid);

filepath = this.blameReaderWriter.WriteTestSequence(this.testSequence, this.testObjectDictionary, filepath);
var fileTranferInformation = new FileTransferInformation(this.context.SessionDataCollectionContext, filepath, true);
this.dataCollectionSink.SendFileAsync(fileTranferInformation);
Expand All @@ -374,7 +397,10 @@ private void SessionEndedHandler(object sender, SessionEndEventArgs args)
if (this.collectProcessDumpOnTrigger)
{
// If there was a test case crash or if we need to collect dump on process exit.
if (this.testStartCount > this.testEndCount || this.collectDumpAlways)
//
// Do not try to collect dump when we already collected one from the hang dump
// we won't dump the killed process again and that would just show a warning on the command line
if ((this.testStartCount > this.testEndCount || this.collectDumpAlways) && !this.dumpWasCollectedByHangDumper)
{
try
{
Expand Down Expand Up @@ -404,7 +430,6 @@ private void SessionEndedHandler(object sender, SessionEndEventArgs args)
if (this.collectProcessDumpOnTrigger)
{
this.processDumpUtility.DetachFromTargetProcess(this.testHostProcessId);
this.processDumpUtility.TerminateProcess();
}

this.DeregisterEvents();
Expand All @@ -428,7 +453,7 @@ private void TestHostLaunchedHandler(object sender, TestHostLaunchedEventArgs ar

try
{
this.processDumpUtility.StartTriggerBasedProcessDump(args.TestHostProcessId, this.attachmentGuid, this.GetResultsDirectory(), this.processFullDumpEnabled);
this.processDumpUtility.StartTriggerBasedProcessDump(args.TestHostProcessId, this.attachmentGuid, this.GetTempDirectory(), this.processFullDumpEnabled, ".NETFramework,Version=v4.0");
}
catch (TestPlatformException e)
{
Expand Down Expand Up @@ -481,24 +506,15 @@ private void DeregisterEvents()
this.events.TestCaseEnd -= this.EventsTestCaseEnd;
}

private string GetResultsDirectory()
private string GetTempDirectory()
{
try
var tmp = Path.GetTempPath();
if (!Directory.Exists(tmp))
{
XmlElement resultsDirectoryElement = this.configurationElement["ResultsDirectory"];
string resultsDirectory = resultsDirectoryElement != null ? resultsDirectoryElement.InnerText : string.Empty;

return Environment.ExpandEnvironmentVariables(resultsDirectory);
Directory.CreateDirectory(tmp);
}
catch (NullReferenceException exception)
{
if (EqtTrace.IsErrorEnabled)
{
EqtTrace.Error("Blame Collector : " + exception);
}

return string.Empty;
}
return tmp;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ internal static class Constants
/// </summary>
public const string DumpModeKey = "CollectDump";

/// <summary>
/// Configuration key name for hang dump mode
/// </summary>
public const string HangDumpModeKey = "CollectHangDump";

/// <summary>
/// Proc dump 32 bit version
/// </summary>
Expand All @@ -63,6 +68,11 @@ internal static class Constants
/// </summary>
public const string Procdump64Process = "procdump64.exe";

/// <summary>
/// Proc dump 64 bit version
/// </summary>
public const string ProcdumpUnixProcess = "procdump";

/// <summary>
/// Configuration key name for collect dump always
/// </summary>
Expand All @@ -85,6 +95,11 @@ internal static class Constants
/// </summary>
public const string DumpTypeKey = "DumpType";

/// <summary>
/// Configuration key name for hang dump type
/// </summary>
public const string HangDumpTypeKey = "HangDumpType";

/// <summary>
/// Configuration value for true
/// </summary>
Expand All @@ -104,5 +119,10 @@ internal static class Constants
/// Configuration value for mini
/// </summary>
public const string MiniConfigurationValue = "Mini";

/// <summary>
/// The target framework of test host.
/// </summary>
public const string TargetFramework = "Framework";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.TestPlatform.Extensions.BlameDataCollector
{
using System;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;

internal class CrashDumperFactory : ICrashDumperFactory
{
public ICrashDumper Create(string targetFramework)
{
EqtTrace.Info($"CrashDumperFactory: Creating dumper for {RuntimeInformation.OSDescription} with target framework {targetFramework}.");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
EqtTrace.Info($"CrashDumperFactory: This is Windows, returning ProcDumpCrashDumper that uses ProcDump utility.");
return new ProcDumpCrashDumper();
}

throw new PlatformNotSupportedException($"Unsupported operating system: {RuntimeInformation.OSDescription}");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.TestPlatform.Extensions.BlameDataCollector
{
public enum DumpTypeOption
{
Full,
WithHeap,
Mini,
}
}
Loading