diff --git a/BenchmarkDotNet.sln b/BenchmarkDotNet.sln
index d51cb4e029..779871f1d1 100644
--- a/BenchmarkDotNet.sln
+++ b/BenchmarkDotNet.sln
@@ -47,13 +47,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarkDotNet.Templates", "templates\BenchmarkDotNet.Templates.csproj", "{B620D10A-CD8E-4A34-8B27-FD6257E63AD0}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarkDotNet.Diagnostics.dotTrace", "src\BenchmarkDotNet.Diagnostics.dotTrace\BenchmarkDotNet.Diagnostics.dotTrace.csproj", "{C5BDA61F-3A56-4B59-901D-0A17E78F4076}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks", "tests\BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks\BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj", "{AACA2C63-A85B-47AB-99FC-72C3FF408B14}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkDotNet.TestAdapter", "src\BenchmarkDotNet.TestAdapter\BenchmarkDotNet.TestAdapter.csproj", "{4C9C89B8-7C4E-4ECF-B3C9-324C8772EDAC}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkDotNet.Diagnostics.dotMemory", "src\BenchmarkDotNet.Diagnostics.dotMemory\BenchmarkDotNet.Diagnostics.dotMemory.csproj", "{2E2283A3-6DA6-4482-8518-99D6D9F689AB}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "JetBrains", "JetBrains", "{AD5887B3-2F6C-48B6-B338-A4E286AFFBBD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkDotNet.Diagnostics.dotMemory", "src\JetBrains\BenchmarkDotNet.Diagnostics.dotMemory\BenchmarkDotNet.Diagnostics.dotMemory.csproj", "{777D5767-4B68-4E83-A445-D1ABAE272718}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkDotNet.Diagnostics.dotTrace", "src\JetBrains\BenchmarkDotNet.Diagnostics.dotTrace\BenchmarkDotNet.Diagnostics.dotTrace.csproj", "{EA2E4258-E639-4C14-9147-B4B062769DFE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -133,10 +135,6 @@ Global
{B620D10A-CD8E-4A34-8B27-FD6257E63AD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B620D10A-CD8E-4A34-8B27-FD6257E63AD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B620D10A-CD8E-4A34-8B27-FD6257E63AD0}.Release|Any CPU.Build.0 = Release|Any CPU
- {C5BDA61F-3A56-4B59-901D-0A17E78F4076}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C5BDA61F-3A56-4B59-901D-0A17E78F4076}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C5BDA61F-3A56-4B59-901D-0A17E78F4076}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C5BDA61F-3A56-4B59-901D-0A17E78F4076}.Release|Any CPU.Build.0 = Release|Any CPU
{AACA2C63-A85B-47AB-99FC-72C3FF408B14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AACA2C63-A85B-47AB-99FC-72C3FF408B14}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AACA2C63-A85B-47AB-99FC-72C3FF408B14}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -145,10 +143,14 @@ Global
{4C9C89B8-7C4E-4ECF-B3C9-324C8772EDAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C9C89B8-7C4E-4ECF-B3C9-324C8772EDAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C9C89B8-7C4E-4ECF-B3C9-324C8772EDAC}.Release|Any CPU.Build.0 = Release|Any CPU
- {2E2283A3-6DA6-4482-8518-99D6D9F689AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2E2283A3-6DA6-4482-8518-99D6D9F689AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2E2283A3-6DA6-4482-8518-99D6D9F689AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2E2283A3-6DA6-4482-8518-99D6D9F689AB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {777D5767-4B68-4E83-A445-D1ABAE272718}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {777D5767-4B68-4E83-A445-D1ABAE272718}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {777D5767-4B68-4E83-A445-D1ABAE272718}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {777D5767-4B68-4E83-A445-D1ABAE272718}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EA2E4258-E639-4C14-9147-B4B062769DFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EA2E4258-E639-4C14-9147-B4B062769DFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EA2E4258-E639-4C14-9147-B4B062769DFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EA2E4258-E639-4C14-9147-B4B062769DFE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -172,10 +174,11 @@ Global
{B4405781-40D3-42B8-B168-00E711FABA15} = {14195214-591A-45B7-851A-19D3BA2413F9}
{D9F5065B-6190-431B-850C-117E3D64AB33} = {D6597E3A-6892-4A68-8E14-042FC941FDA2}
{B620D10A-CD8E-4A34-8B27-FD6257E63AD0} = {63B94FD6-3F3D-4E04-9727-48E86AC4384C}
- {C5BDA61F-3A56-4B59-901D-0A17E78F4076} = {D6597E3A-6892-4A68-8E14-042FC941FDA2}
{AACA2C63-A85B-47AB-99FC-72C3FF408B14} = {14195214-591A-45B7-851A-19D3BA2413F9}
{4C9C89B8-7C4E-4ECF-B3C9-324C8772EDAC} = {D6597E3A-6892-4A68-8E14-042FC941FDA2}
- {2E2283A3-6DA6-4482-8518-99D6D9F689AB} = {D6597E3A-6892-4A68-8E14-042FC941FDA2}
+ {AD5887B3-2F6C-48B6-B338-A4E286AFFBBD} = {D6597E3A-6892-4A68-8E14-042FC941FDA2}
+ {777D5767-4B68-4E83-A445-D1ABAE272718} = {AD5887B3-2F6C-48B6-B338-A4E286AFFBBD}
+ {EA2E4258-E639-4C14-9147-B4B062769DFE} = {AD5887B3-2F6C-48B6-B338-A4E286AFFBBD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4D9AF12B-1F7F-45A7-9E8C-E4E46ADCBD1F}
diff --git a/build/BenchmarkDotNet.Build/BuildContext.cs b/build/BenchmarkDotNet.Build/BuildContext.cs
index 0a165721e0..d8f6335147 100644
--- a/build/BenchmarkDotNet.Build/BuildContext.cs
+++ b/build/BenchmarkDotNet.Build/BuildContext.cs
@@ -137,6 +137,13 @@ public BuildContext(ICakeContext context)
.GetSubDirectories(RootDirectory.Combine("src"))
.Select(directoryPath => directoryPath.GetDirectoryName())
.Where(name => !name.Contains("Disassembler", StringComparison.OrdinalIgnoreCase)));
+
+ var jetBrainsNugetPackages = this
+ .GetSubDirectories(RootDirectory.Combine("src/JetBrains"))
+ .Select(directoryPath => directoryPath.GetDirectoryName())
+ .Where(name => name != "Shared");
+ nuGetPackageNames.AddRange(jetBrainsNugetPackages);
+
nuGetPackageNames.Add("BenchmarkDotNet.Templates");
nuGetPackageNames.Sort();
NuGetPackageNames = nuGetPackageNames;
diff --git a/samples/BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj b/samples/BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj
index 36c3f60b32..ab7928a940 100644
--- a/samples/BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj
+++ b/samples/BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj
@@ -25,8 +25,8 @@
-
-
+
+
diff --git a/src/BenchmarkDotNet.Diagnostics.dotMemory/Progress.cs b/src/BenchmarkDotNet.Diagnostics.dotMemory/Progress.cs
deleted file mode 100644
index 738997bb6d..0000000000
--- a/src/BenchmarkDotNet.Diagnostics.dotMemory/Progress.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using System.Diagnostics;
-using BenchmarkDotNet.Loggers;
-
-namespace BenchmarkDotNet.Diagnostics.dotMemory
-{
- public class Progress : IProgress
- {
- private static readonly TimeSpan ReportInterval = TimeSpan.FromSeconds(0.1);
-
- private readonly ILogger logger;
- private readonly string title;
-
- public Progress(ILogger logger, string title)
- {
- this.logger = logger;
- this.title = title;
- }
-
- private int lastProgress;
- private Stopwatch? stopwatch;
-
- public void Report(double value)
- {
- int progress = (int)Math.Floor(value);
- bool needToReport = stopwatch == null ||
- (stopwatch != null && stopwatch?.Elapsed > ReportInterval) ||
- progress == 100;
-
- if (lastProgress != progress && needToReport)
- {
- logger.WriteLineInfo($"{title}: {progress}%");
- lastProgress = progress;
- stopwatch = Stopwatch.StartNew();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceToolBase.cs b/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceToolBase.cs
deleted file mode 100644
index f2f07625fa..0000000000
--- a/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceToolBase.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-using System;
-using System.IO;
-using System.Reflection;
-using BenchmarkDotNet.Diagnosers;
-using BenchmarkDotNet.Helpers;
-using BenchmarkDotNet.Loggers;
-using JetBrains.Profiler.SelfApi;
-
-namespace BenchmarkDotNet.Diagnostics.dotTrace
-{
- internal abstract class DotTraceToolBase
- {
- private readonly ILogger logger;
- private readonly Uri? nugetUrl;
- private readonly NuGetApi nugetApi;
- private readonly string? downloadTo;
-
- protected DotTraceToolBase(ILogger logger, Uri? nugetUrl = null, NuGetApi nugetApi = NuGetApi.V3, string? downloadTo = null)
- {
- this.logger = logger;
- this.nugetUrl = nugetUrl;
- this.nugetApi = nugetApi;
- this.downloadTo = downloadTo;
- }
-
- public void Init(DiagnoserActionParameters parameters)
- {
- try
- {
- logger.WriteLineInfo("Ensuring that dotTrace prerequisite is installed...");
- var progress = new Progress(logger, "Installing DotTrace");
- DotTrace.EnsurePrerequisiteAsync(progress, nugetUrl, nugetApi, downloadTo).Wait();
- logger.WriteLineInfo("dotTrace prerequisite is installed");
- logger.WriteLineInfo($"dotTrace runner path: {GetRunnerPath()}");
- }
- catch (Exception e)
- {
- logger.WriteLineError(e.ToString());
- }
- }
-
- protected abstract bool AttachOnly { get; }
- protected abstract void Attach(DiagnoserActionParameters parameters, string snapshotFile);
- protected abstract void StartCollectingData();
- protected abstract void SaveData();
- protected abstract void Detach();
-
- public string Start(DiagnoserActionParameters parameters)
- {
- string snapshotFile = ArtifactFileNameHelper.GetFilePath(parameters, "snapshots", DateTime.Now, "dtp", ".0000".Length);
- string? snapshotDirectory = Path.GetDirectoryName(snapshotFile);
- logger.WriteLineInfo($"Target snapshot file: {snapshotFile}");
- if (!Directory.Exists(snapshotDirectory) && snapshotDirectory != null)
- {
- try
- {
- Directory.CreateDirectory(snapshotDirectory);
- }
- catch (Exception e)
- {
- logger.WriteLineError($"Failed to create directory: {snapshotDirectory}");
- logger.WriteLineError(e.ToString());
- }
- }
-
- try
- {
- logger.WriteLineInfo("Attaching dotTrace to the process...");
- Attach(parameters, snapshotFile);
- logger.WriteLineInfo("dotTrace is successfully attached");
- }
- catch (Exception e)
- {
- logger.WriteLineError(e.ToString());
- return snapshotFile;
- }
-
- if (!AttachOnly)
- {
- try
- {
- logger.WriteLineInfo("Start collecting data using dataTrace...");
- StartCollectingData();
- logger.WriteLineInfo("Data collecting is successfully started");
- }
- catch (Exception e)
- {
- logger.WriteLineError(e.ToString());
- }
- }
-
- return snapshotFile;
- }
-
- public void Stop(DiagnoserActionParameters parameters)
- {
- if (!AttachOnly)
- {
- try
- {
- logger.WriteLineInfo("Saving dotTrace snapshot...");
- SaveData();
- logger.WriteLineInfo("dotTrace snapshot is successfully saved to the artifact folder");
- }
- catch (Exception e)
- {
- logger.WriteLineError(e.ToString());
- }
-
- try
- {
- logger.WriteLineInfo("Detaching dotTrace from the process...");
- Detach();
- logger.WriteLineInfo("dotTrace is successfully detached");
- }
- catch (Exception e)
- {
- logger.WriteLineError(e.ToString());
- }
- }
- }
-
- protected string GetRunnerPath()
- {
- var consoleRunnerPackageField = typeof(DotTrace).GetField("ConsoleRunnerPackage", BindingFlags.NonPublic | BindingFlags.Static);
- if (consoleRunnerPackageField == null)
- throw new InvalidOperationException("Field 'ConsoleRunnerPackage' not found.");
-
- object? consoleRunnerPackage = consoleRunnerPackageField.GetValue(null);
- if (consoleRunnerPackage == null)
- throw new InvalidOperationException("Unable to get value of 'ConsoleRunnerPackage'.");
-
- var consoleRunnerPackageType = consoleRunnerPackage.GetType();
- var getRunnerPathMethod = consoleRunnerPackageType.GetMethod("GetRunnerPath");
- if (getRunnerPathMethod == null)
- throw new InvalidOperationException("Method 'GetRunnerPath' not found.");
-
- string? runnerPath = getRunnerPathMethod.Invoke(consoleRunnerPackage, null) as string;
- if (runnerPath == null)
- throw new InvalidOperationException("Unable to invoke 'GetRunnerPath'.");
-
- return runnerPath;
- }
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet.Diagnostics.dotTrace/ExternalDotTraceTool.cs b/src/BenchmarkDotNet.Diagnostics.dotTrace/ExternalDotTraceTool.cs
deleted file mode 100644
index c7f1cf18c8..0000000000
--- a/src/BenchmarkDotNet.Diagnostics.dotTrace/ExternalDotTraceTool.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Threading.Tasks;
-using BenchmarkDotNet.Diagnosers;
-using BenchmarkDotNet.Loggers;
-using JetBrains.Profiler.SelfApi;
-using ILogger = BenchmarkDotNet.Loggers.ILogger;
-
-namespace BenchmarkDotNet.Diagnostics.dotTrace
-{
- internal class ExternalDotTraceTool : DotTraceToolBase
- {
- private static readonly TimeSpan AttachTimeout = TimeSpan.FromMinutes(5);
-
- public ExternalDotTraceTool(ILogger logger, Uri? nugetUrl = null, NuGetApi nugetApi = NuGetApi.V3, string? downloadTo = null) :
- base(logger, nugetUrl, nugetApi, downloadTo) { }
-
- protected override bool AttachOnly => true;
-
- protected override void Attach(DiagnoserActionParameters parameters, string snapshotFile)
- {
- var logger = parameters.Config.GetCompositeLogger();
-
- string runnerPath = GetRunnerPath();
- int pid = parameters.Process.Id;
- string arguments = $"attach {pid} --save-to=\"{snapshotFile}\" --service-output=on";
-
- logger.WriteLineInfo($"Starting process: '{runnerPath} {arguments}'");
-
- var processStartInfo = new ProcessStartInfo
- {
- FileName = runnerPath,
- WorkingDirectory = "",
- Arguments = arguments,
- UseShellExecute = false,
- CreateNoWindow = true,
- RedirectStandardOutput = true,
- RedirectStandardError = true
- };
-
- var attachWaitingTask = new TaskCompletionSource();
- var process = new Process { StartInfo = processStartInfo };
- try
- {
- process.OutputDataReceived += (_, args) =>
- {
- string? content = args.Data;
- if (content != null)
- {
- logger.WriteLineInfo("[dotTrace] " + content);
- if (content.Contains("##dotTrace[\"started\""))
- attachWaitingTask.TrySetResult(true);
- }
- };
- process.ErrorDataReceived += (_, args) =>
- {
- string? content = args.Data;
- if (content != null)
- logger.WriteLineError("[dotTrace] " + args.Data);
- };
- process.Exited += (_, _) => { attachWaitingTask.TrySetResult(false); };
- process.Start();
- process.BeginOutputReadLine();
- process.BeginErrorReadLine();
- }
- catch (Exception e)
- {
- attachWaitingTask.TrySetResult(false);
- logger.WriteLineError(e.ToString());
- }
-
- if (!attachWaitingTask.Task.Wait(AttachTimeout))
- throw new Exception($"Failed to attach dotTrace to the target process (timeout: {AttachTimeout.TotalSeconds} sec)");
- if (!attachWaitingTask.Task.Result)
- throw new Exception($"Failed to attach dotTrace to the target process (ExitCode={process.ExitCode})");
- }
-
- protected override void StartCollectingData() { }
-
- protected override void SaveData() { }
-
- protected override void Detach() { }
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet.Diagnostics.dotTrace/InProcessDotTraceTool.cs b/src/BenchmarkDotNet.Diagnostics.dotTrace/InProcessDotTraceTool.cs
deleted file mode 100644
index a02c9c1995..0000000000
--- a/src/BenchmarkDotNet.Diagnostics.dotTrace/InProcessDotTraceTool.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using BenchmarkDotNet.Diagnosers;
-using BenchmarkDotNet.Loggers;
-using JetBrains.Profiler.SelfApi;
-
-namespace BenchmarkDotNet.Diagnostics.dotTrace
-{
- internal class InProcessDotTraceTool : DotTraceToolBase
- {
- public InProcessDotTraceTool(ILogger logger, Uri? nugetUrl = null, NuGetApi nugetApi = NuGetApi.V3, string? downloadTo = null) :
- base(logger, nugetUrl, nugetApi, downloadTo) { }
-
- protected override bool AttachOnly => false;
-
- protected override void Attach(DiagnoserActionParameters parameters, string snapshotFile)
- {
- var config = new DotTrace.Config();
- config.SaveToFile(snapshotFile);
- DotTrace.Attach(config);
- }
-
- protected override void StartCollectingData() => DotTrace.StartCollectingData();
-
- protected override void SaveData() => DotTrace.SaveData();
-
- protected override void Detach() => DotTrace.Detach();
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet.Diagnostics.dotMemory/BenchmarkDotNet.Diagnostics.dotMemory.csproj b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/BenchmarkDotNet.Diagnostics.dotMemory.csproj
similarity index 73%
rename from src/BenchmarkDotNet.Diagnostics.dotMemory/BenchmarkDotNet.Diagnostics.dotMemory.csproj
rename to src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/BenchmarkDotNet.Diagnostics.dotMemory.csproj
index 23261abb24..d418341924 100644
--- a/src/BenchmarkDotNet.Diagnostics.dotMemory/BenchmarkDotNet.Diagnostics.dotMemory.csproj
+++ b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/BenchmarkDotNet.Diagnostics.dotMemory.csproj
@@ -1,5 +1,5 @@
-
+
net6.0;net462;netcoreapp3.1
$(NoWarn);1591
@@ -10,7 +10,11 @@
-
+
+
+
+
+
diff --git a/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs
similarity index 59%
rename from src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs
rename to src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs
index 46789b518c..16ae55eb41 100644
--- a/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs
+++ b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs
@@ -6,9 +6,9 @@
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Exporters;
+using BenchmarkDotNet.JetBrains;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Loggers;
-using BenchmarkDotNet.Portability;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Validators;
@@ -77,60 +77,7 @@ public IEnumerable Validate(ValidationParameters validationPara
}
}
- internal static bool IsSupported(RuntimeMoniker runtimeMoniker)
- {
- switch (runtimeMoniker)
- {
- case RuntimeMoniker.HostProcess:
- case RuntimeMoniker.Net461:
- case RuntimeMoniker.Net462:
- case RuntimeMoniker.Net47:
- case RuntimeMoniker.Net471:
- case RuntimeMoniker.Net472:
- case RuntimeMoniker.Net48:
- case RuntimeMoniker.Net481:
- case RuntimeMoniker.Net50:
- case RuntimeMoniker.Net60:
- case RuntimeMoniker.Net70:
- case RuntimeMoniker.Net80:
- case RuntimeMoniker.Net90:
- return true;
- case RuntimeMoniker.NotRecognized:
- case RuntimeMoniker.Mono:
- case RuntimeMoniker.NativeAot60:
- case RuntimeMoniker.NativeAot70:
- case RuntimeMoniker.NativeAot80:
- case RuntimeMoniker.NativeAot90:
- case RuntimeMoniker.Wasm:
- case RuntimeMoniker.WasmNet50:
- case RuntimeMoniker.WasmNet60:
- case RuntimeMoniker.WasmNet70:
- case RuntimeMoniker.WasmNet80:
- case RuntimeMoniker.WasmNet90:
- case RuntimeMoniker.MonoAOTLLVM:
- case RuntimeMoniker.MonoAOTLLVMNet60:
- case RuntimeMoniker.MonoAOTLLVMNet70:
- case RuntimeMoniker.MonoAOTLLVMNet80:
- case RuntimeMoniker.MonoAOTLLVMNet90:
- case RuntimeMoniker.Mono60:
- case RuntimeMoniker.Mono70:
- case RuntimeMoniker.Mono80:
- case RuntimeMoniker.Mono90:
-#pragma warning disable CS0618 // Type or member is obsolete
- case RuntimeMoniker.NetCoreApp50:
-#pragma warning restore CS0618 // Type or member is obsolete
- return false;
- case RuntimeMoniker.NetCoreApp20:
- case RuntimeMoniker.NetCoreApp21:
- case RuntimeMoniker.NetCoreApp22:
- return RuntimeInformation.IsWindows();
- case RuntimeMoniker.NetCoreApp30:
- case RuntimeMoniker.NetCoreApp31:
- return RuntimeInformation.IsWindows() || RuntimeInformation.IsLinux();
- default:
- throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, $"Runtime moniker {runtimeMoniker} is not supported");
- }
- }
+ internal static bool IsSupported(RuntimeMoniker runtimeMoniker) => Helper.IsSupported(runtimeMoniker);
public IEnumerable ProcessResults(DiagnoserResults results) => ImmutableArray.Empty;
diff --git a/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoserAttribute.cs b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoserAttribute.cs
similarity index 100%
rename from src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoserAttribute.cs
rename to src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoserAttribute.cs
diff --git a/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryTool.cs b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryTool.cs
similarity index 75%
rename from src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryTool.cs
rename to src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryTool.cs
index 1e640d6708..3e0cd342f2 100644
--- a/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryTool.cs
+++ b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryTool.cs
@@ -1,11 +1,11 @@
using System;
using System.Diagnostics;
using System.IO;
-using System.Reflection;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Helpers;
using BenchmarkDotNet.Loggers;
using JetBrains.Profiler.SelfApi;
+using BenchmarkDotNet.JetBrains;
namespace BenchmarkDotNet.Diagnostics.dotMemory
{
@@ -32,7 +32,7 @@ public void Init()
var progress = new Progress(logger, "Installing DotMemory");
DotMemory.EnsurePrerequisiteAsync(progress, nugetUrl, nugetApi, downloadTo).Wait();
logger.WriteLineInfo("dotMemory prerequisite is installed");
- logger.WriteLineInfo($"dotMemory runner path: {GetRunnerPath()}");
+ logger.WriteLineInfo($"dotMemory runner path: {Helper.GetRunnerPath(typeof(DotMemory))}");
}
catch (Exception e)
{
@@ -114,27 +114,5 @@ private void Attach(DiagnoserActionParameters parameters, string snapshotFile)
private void Snapshot() => DotMemory.GetSnapshot();
private void Detach() => DotMemory.Detach();
-
- private string GetRunnerPath()
- {
- var consoleRunnerPackageField = typeof(DotMemory).GetField("ConsoleRunnerPackage", BindingFlags.NonPublic | BindingFlags.Static);
- if (consoleRunnerPackageField == null)
- throw new InvalidOperationException("Field 'ConsoleRunnerPackage' not found.");
-
- object? consoleRunnerPackage = consoleRunnerPackageField.GetValue(null);
- if (consoleRunnerPackage == null)
- throw new InvalidOperationException("Unable to get value of 'ConsoleRunnerPackage'.");
-
- var consoleRunnerPackageType = consoleRunnerPackage.GetType();
- var getRunnerPathMethod = consoleRunnerPackageType.GetMethod("GetRunnerPath");
- if (getRunnerPathMethod == null)
- throw new InvalidOperationException("Method 'GetRunnerPath' not found.");
-
- string? runnerPath = getRunnerPathMethod.Invoke(consoleRunnerPackage, null) as string;
- if (runnerPath == null)
- throw new InvalidOperationException("Unable to invoke 'GetRunnerPath'.");
-
- return runnerPath;
- }
}
}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet.Diagnostics.dotMemory/Properties/AssemblyInfo.cs b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/Properties/AssemblyInfo.cs
similarity index 100%
rename from src/BenchmarkDotNet.Diagnostics.dotMemory/Properties/AssemblyInfo.cs
rename to src/JetBrains/BenchmarkDotNet.Diagnostics.dotMemory/Properties/AssemblyInfo.cs
diff --git a/src/BenchmarkDotNet.Diagnostics.dotTrace/BenchmarkDotNet.Diagnostics.dotTrace.csproj b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/BenchmarkDotNet.Diagnostics.dotTrace.csproj
similarity index 73%
rename from src/BenchmarkDotNet.Diagnostics.dotTrace/BenchmarkDotNet.Diagnostics.dotTrace.csproj
rename to src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/BenchmarkDotNet.Diagnostics.dotTrace.csproj
index aa8c7af1e4..e6e1cb5ef9 100644
--- a/src/BenchmarkDotNet.Diagnostics.dotTrace/BenchmarkDotNet.Diagnostics.dotTrace.csproj
+++ b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/BenchmarkDotNet.Diagnostics.dotTrace.csproj
@@ -1,5 +1,5 @@
-
+
net6.0;net462;netcoreapp3.1
$(NoWarn);1591
@@ -10,7 +10,11 @@
-
+
+
+
+
+
diff --git a/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs
similarity index 51%
rename from src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs
rename to src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs
index 2aada424b7..19f8773343 100644
--- a/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs
+++ b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs
@@ -6,12 +6,11 @@
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Exporters;
+using BenchmarkDotNet.JetBrains;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Loggers;
-using BenchmarkDotNet.Portability;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Running;
-using BenchmarkDotNet.Toolchains;
using BenchmarkDotNet.Validators;
using RunMode = BenchmarkDotNet.Diagnosers.RunMode;
@@ -19,6 +18,8 @@ namespace BenchmarkDotNet.Diagnostics.dotTrace
{
public class DotTraceDiagnoser(Uri? nugetUrl = null, string? toolsDownloadFolder = null) : IProfiler
{
+ private DotTraceTool? tool;
+
public IEnumerable Ids => new[] { "DotTrace" };
public string ShortName => "dotTrace";
@@ -32,11 +33,7 @@ public RunMode GetRunMode(BenchmarkCase benchmarkCase)
public void Handle(HostSignal signal, DiagnoserActionParameters parameters)
{
var job = parameters.BenchmarkCase.Job;
- bool isInProcess = job.GetToolchain().IsInProcess;
var logger = parameters.Config.GetCompositeLogger();
- DotTraceToolBase tool = isInProcess
- ? new InProcessDotTraceTool(logger, nugetUrl, downloadTo: toolsDownloadFolder)
- : new ExternalDotTraceTool(logger, nugetUrl, downloadTo: toolsDownloadFolder);
var runtimeMoniker = job.Environment.GetRuntime().RuntimeMoniker;
if (!IsSupported(runtimeMoniker))
@@ -48,13 +45,21 @@ public void Handle(HostSignal signal, DiagnoserActionParameters parameters)
switch (signal)
{
case HostSignal.BeforeAnythingElse:
- tool.Init(parameters);
+ if (tool is not null)
+ throw new InvalidOperationException("dotTrace tool is already initialized");
+ tool = new DotTraceTool(logger, nugetUrl, downloadTo: toolsDownloadFolder);
+ tool.Init();
break;
case HostSignal.BeforeActualRun:
+ if (tool is null)
+ throw new InvalidOperationException("dotTrace tool is not initialized");
snapshotFilePaths.Add(tool.Start(parameters));
break;
case HostSignal.AfterActualRun:
- tool.Stop(parameters);
+ if (tool is null)
+ throw new InvalidOperationException("dotTrace tool is not initialized");
+ tool.Stop();
+ tool = null;
break;
}
}
@@ -72,60 +77,7 @@ public IEnumerable Validate(ValidationParameters validationPara
}
}
- internal static bool IsSupported(RuntimeMoniker runtimeMoniker)
- {
- switch (runtimeMoniker)
- {
- case RuntimeMoniker.HostProcess:
- case RuntimeMoniker.Net461:
- case RuntimeMoniker.Net462:
- case RuntimeMoniker.Net47:
- case RuntimeMoniker.Net471:
- case RuntimeMoniker.Net472:
- case RuntimeMoniker.Net48:
- case RuntimeMoniker.Net481:
- case RuntimeMoniker.Net50:
- case RuntimeMoniker.Net60:
- case RuntimeMoniker.Net70:
- case RuntimeMoniker.Net80:
- case RuntimeMoniker.Net90:
- return true;
- case RuntimeMoniker.NotRecognized:
- case RuntimeMoniker.Mono:
- case RuntimeMoniker.NativeAot60:
- case RuntimeMoniker.NativeAot70:
- case RuntimeMoniker.NativeAot80:
- case RuntimeMoniker.NativeAot90:
- case RuntimeMoniker.Wasm:
- case RuntimeMoniker.WasmNet50:
- case RuntimeMoniker.WasmNet60:
- case RuntimeMoniker.WasmNet70:
- case RuntimeMoniker.WasmNet80:
- case RuntimeMoniker.WasmNet90:
- case RuntimeMoniker.MonoAOTLLVM:
- case RuntimeMoniker.MonoAOTLLVMNet60:
- case RuntimeMoniker.MonoAOTLLVMNet70:
- case RuntimeMoniker.MonoAOTLLVMNet80:
- case RuntimeMoniker.MonoAOTLLVMNet90:
- case RuntimeMoniker.Mono60:
- case RuntimeMoniker.Mono70:
- case RuntimeMoniker.Mono80:
- case RuntimeMoniker.Mono90:
-#pragma warning disable CS0618 // Type or member is obsolete
- case RuntimeMoniker.NetCoreApp50:
-#pragma warning restore CS0618 // Type or member is obsolete
- return false;
- case RuntimeMoniker.NetCoreApp20:
- case RuntimeMoniker.NetCoreApp21:
- case RuntimeMoniker.NetCoreApp22:
- return RuntimeInformation.IsWindows();
- case RuntimeMoniker.NetCoreApp30:
- case RuntimeMoniker.NetCoreApp31:
- return RuntimeInformation.IsWindows() || RuntimeInformation.IsLinux();
- default:
- throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, $"Runtime moniker {runtimeMoniker} is not supported");
- }
- }
+ internal static bool IsSupported(RuntimeMoniker runtimeMoniker) => Helper.IsSupported(runtimeMoniker);
public IEnumerable ProcessResults(DiagnoserResults results) => ImmutableArray.Empty;
diff --git a/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoserAttribute.cs b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoserAttribute.cs
similarity index 100%
rename from src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoserAttribute.cs
rename to src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoserAttribute.cs
diff --git a/src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceTool.cs b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceTool.cs
new file mode 100644
index 0000000000..1214b3b92e
--- /dev/null
+++ b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceTool.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using BenchmarkDotNet.Diagnosers;
+using BenchmarkDotNet.Helpers;
+using BenchmarkDotNet.Loggers;
+using JetBrains.Profiler.SelfApi;
+using BenchmarkDotNet.JetBrains;
+
+namespace BenchmarkDotNet.Diagnostics.dotTrace
+{
+ internal sealed class DotTraceTool
+ {
+ private readonly ILogger logger;
+ private readonly Uri? nugetUrl;
+ private readonly NuGetApi nugetApi;
+ private readonly string? downloadTo;
+
+ public DotTraceTool(ILogger logger, Uri? nugetUrl = null, NuGetApi nugetApi = NuGetApi.V3, string? downloadTo = null)
+ {
+ this.logger = logger;
+ this.nugetUrl = nugetUrl;
+ this.nugetApi = nugetApi;
+ this.downloadTo = downloadTo;
+ }
+
+ public void Init()
+ {
+ try
+ {
+ logger.WriteLineInfo("Ensuring that dotTrace prerequisite is installed...");
+ var progress = new Progress(logger, "Installing DotTrace");
+ DotTrace.EnsurePrerequisiteAsync(progress, nugetUrl, nugetApi, downloadTo).Wait();
+ logger.WriteLineInfo("dotTrace prerequisite is installed");
+ logger.WriteLineInfo($"dotTrace runner path: {Helper.GetRunnerPath(typeof(DotTrace))}");
+ }
+ catch (Exception e)
+ {
+ logger.WriteLineError(e.ToString());
+ }
+ }
+
+ public string Start(DiagnoserActionParameters parameters)
+ {
+ string snapshotFile = ArtifactFileNameHelper.GetFilePath(parameters, "snapshots", DateTime.Now, "dtp", ".0000".Length);
+ string? snapshotDirectory = Path.GetDirectoryName(snapshotFile);
+ logger.WriteLineInfo($"Target snapshot file: {snapshotFile}");
+ if (!Directory.Exists(snapshotDirectory) && snapshotDirectory != null)
+ {
+ try
+ {
+ Directory.CreateDirectory(snapshotDirectory);
+ }
+ catch (Exception e)
+ {
+ logger.WriteLineError($"Failed to create directory: {snapshotDirectory}");
+ logger.WriteLineError(e.ToString());
+ }
+ }
+
+ try
+ {
+ logger.WriteLineInfo("Attaching dotTrace to the process...");
+ Attach(parameters, snapshotFile);
+ logger.WriteLineInfo("dotTrace is successfully attached");
+ }
+ catch (Exception e)
+ {
+ logger.WriteLineError(e.ToString());
+ return snapshotFile;
+ }
+
+ try
+ {
+ logger.WriteLineInfo("Start collecting data using dotTrace...");
+ StartCollectingData();
+ logger.WriteLineInfo("Data collection has successfully started");
+ }
+ catch (Exception e)
+ {
+ logger.WriteLineError(e.ToString());
+ }
+
+ return snapshotFile;
+ }
+
+ public void Stop()
+ {
+ try
+ {
+ logger.WriteLineInfo("Saving dotTrace snapshot...");
+ SaveData();
+ logger.WriteLineInfo("dotTrace snapshot is successfully saved to the artifact folder");
+ }
+ catch (Exception e)
+ {
+ logger.WriteLineError(e.ToString());
+ }
+
+ try
+ {
+ logger.WriteLineInfo("Detaching dotTrace from the process...");
+ Detach();
+ logger.WriteLineInfo("dotTrace is successfully detached");
+ }
+ catch (Exception e)
+ {
+ logger.WriteLineError(e.ToString());
+ }
+ }
+
+ private void Attach(DiagnoserActionParameters parameters, string snapshotFile)
+ {
+ var config = new DotTrace.Config();
+
+ var pid = parameters.Process.Id;
+ var currentPid = Process.GetCurrentProcess().Id;
+ if (pid != currentPid)
+ config = config.ProfileExternalProcess(pid);
+
+ config = config.SaveToFile(snapshotFile);
+ DotTrace.Attach(config);
+ }
+
+ private void StartCollectingData() => DotTrace.StartCollectingData();
+
+ private void SaveData() => DotTrace.SaveData();
+
+ private void Detach() => DotTrace.Detach();
+ }
+}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet.Diagnostics.dotTrace/Properties/AssemblyInfo.cs b/src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/Properties/AssemblyInfo.cs
similarity index 100%
rename from src/BenchmarkDotNet.Diagnostics.dotTrace/Properties/AssemblyInfo.cs
rename to src/JetBrains/BenchmarkDotNet.Diagnostics.dotTrace/Properties/AssemblyInfo.cs
diff --git a/src/JetBrains/Shared/Helper.cs b/src/JetBrains/Shared/Helper.cs
new file mode 100644
index 0000000000..020b659a6c
--- /dev/null
+++ b/src/JetBrains/Shared/Helper.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Reflection;
+using BenchmarkDotNet.Jobs;
+using BenchmarkDotNet.Portability;
+
+namespace BenchmarkDotNet.JetBrains
+{
+ internal static class Helper
+ {
+ internal static bool IsSupported(RuntimeMoniker runtimeMoniker)
+ {
+ switch (runtimeMoniker)
+ {
+ case RuntimeMoniker.HostProcess:
+ case RuntimeMoniker.Net461:
+ case RuntimeMoniker.Net462:
+ case RuntimeMoniker.Net47:
+ case RuntimeMoniker.Net471:
+ case RuntimeMoniker.Net472:
+ case RuntimeMoniker.Net48:
+ case RuntimeMoniker.Net481:
+ case RuntimeMoniker.Net50:
+ case RuntimeMoniker.Net60:
+ case RuntimeMoniker.Net70:
+ case RuntimeMoniker.Net80:
+ case RuntimeMoniker.Net90:
+ return true;
+ case RuntimeMoniker.NotRecognized:
+ case RuntimeMoniker.Mono:
+ case RuntimeMoniker.NativeAot60:
+ case RuntimeMoniker.NativeAot70:
+ case RuntimeMoniker.NativeAot80:
+ case RuntimeMoniker.NativeAot90:
+ case RuntimeMoniker.Wasm:
+ case RuntimeMoniker.WasmNet50:
+ case RuntimeMoniker.WasmNet60:
+ case RuntimeMoniker.WasmNet70:
+ case RuntimeMoniker.WasmNet80:
+ case RuntimeMoniker.WasmNet90:
+ case RuntimeMoniker.MonoAOTLLVM:
+ case RuntimeMoniker.MonoAOTLLVMNet60:
+ case RuntimeMoniker.MonoAOTLLVMNet70:
+ case RuntimeMoniker.MonoAOTLLVMNet80:
+ case RuntimeMoniker.MonoAOTLLVMNet90:
+ case RuntimeMoniker.Mono60:
+ case RuntimeMoniker.Mono70:
+ case RuntimeMoniker.Mono80:
+ case RuntimeMoniker.Mono90:
+#pragma warning disable CS0618 // Type or member is obsolete
+ case RuntimeMoniker.NetCoreApp50:
+#pragma warning restore CS0618 // Type or member is obsolete
+ return false;
+ case RuntimeMoniker.NetCoreApp20:
+ case RuntimeMoniker.NetCoreApp21:
+ case RuntimeMoniker.NetCoreApp22:
+ return RuntimeInformation.IsWindows();
+ case RuntimeMoniker.NetCoreApp30:
+ case RuntimeMoniker.NetCoreApp31:
+ return RuntimeInformation.IsWindows() || RuntimeInformation.IsLinux();
+ default:
+ throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, $"Runtime moniker {runtimeMoniker} is not supported");
+ }
+ }
+
+ internal static string GetRunnerPath(Type type)
+ {
+ var consoleRunnerPackageField = type.GetField("ConsoleRunnerPackage", BindingFlags.NonPublic | BindingFlags.Static);
+ if (consoleRunnerPackageField == null)
+ throw new InvalidOperationException("Field 'ConsoleRunnerPackage' not found.");
+
+ object? consoleRunnerPackage = consoleRunnerPackageField.GetValue(null);
+ if (consoleRunnerPackage == null)
+ throw new InvalidOperationException("Unable to get value of 'ConsoleRunnerPackage'.");
+
+ var consoleRunnerPackageType = consoleRunnerPackage.GetType();
+ var getRunnerPathMethod = consoleRunnerPackageType.GetMethod("GetRunnerPath");
+ if (getRunnerPathMethod == null)
+ throw new InvalidOperationException("Method 'GetRunnerPath' not found.");
+
+ string? runnerPath = getRunnerPathMethod.Invoke(consoleRunnerPackage, null) as string;
+ if (runnerPath == null)
+ throw new InvalidOperationException("Unable to invoke 'GetRunnerPath'.");
+
+ return runnerPath;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet.Diagnostics.dotTrace/Progress.cs b/src/JetBrains/Shared/Progress.cs
similarity index 91%
rename from src/BenchmarkDotNet.Diagnostics.dotTrace/Progress.cs
rename to src/JetBrains/Shared/Progress.cs
index c353939f1f..f09371412f 100644
--- a/src/BenchmarkDotNet.Diagnostics.dotTrace/Progress.cs
+++ b/src/JetBrains/Shared/Progress.cs
@@ -2,9 +2,9 @@
using System.Diagnostics;
using BenchmarkDotNet.Loggers;
-namespace BenchmarkDotNet.Diagnostics.dotTrace
+namespace BenchmarkDotNet.JetBrains
{
- public class Progress : IProgress
+ internal sealed class Progress : IProgress
{
private static readonly TimeSpan ReportInterval = TimeSpan.FromSeconds(0.1);
diff --git a/tests/BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj b/tests/BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj
index a928af1424..d16cfcb9cb 100644
--- a/tests/BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj
+++ b/tests/BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj
@@ -28,8 +28,8 @@
-
-
+
+
diff --git a/tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj b/tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj
index fcdc416bbf..f03cf5e344 100755
--- a/tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj
+++ b/tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj
@@ -35,8 +35,8 @@
-
-
+
+