Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
allow the users to run benchmarks with CoreRun, #857
- Loading branch information
1 parent
20e9015
commit de152c7
Showing
7 changed files
with
292 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
src/BenchmarkDotNet/Toolchains/CoreRun/CoreRunGenerator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using System; | ||
using System.IO; | ||
using System.Linq; | ||
using BenchmarkDotNet.Environments; | ||
using BenchmarkDotNet.Toolchains.CsProj; | ||
|
||
namespace BenchmarkDotNet.Toolchains.CoreRun | ||
{ | ||
public class CoreRunGenerator : CsProjGenerator | ||
{ | ||
public CoreRunGenerator(FileInfo sourceCoreRun, FileInfo copyCoreRun, string targetFrameworkMoniker, Func<Platform, string> platformProvider) | ||
: base(targetFrameworkMoniker, platformProvider) | ||
{ | ||
SourceCoreRun = sourceCoreRun; | ||
CopyCoreRun = copyCoreRun; | ||
} | ||
|
||
private FileInfo SourceCoreRun { get; } | ||
|
||
private FileInfo CopyCoreRun { get; } | ||
|
||
private bool NeedsCopy => SourceCoreRun != CopyCoreRun; | ||
|
||
protected override string GetPackagesDirectoryPath(string buildArtifactsDirectoryPath) | ||
=> null; // we don't want to restore to a dedicated folder | ||
|
||
protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration) | ||
=> Path.Combine(buildArtifactsDirectoryPath, "bin", configuration, TargetFrameworkMoniker, "publish"); | ||
|
||
protected override void CopyAllRequiredFiles(ArtifactsPaths artifactsPaths) | ||
{ | ||
if (NeedsCopy) | ||
CopyFilesRecursively(SourceCoreRun.Directory, CopyCoreRun.Directory); | ||
|
||
base.CopyAllRequiredFiles(artifactsPaths); | ||
} | ||
|
||
protected override string[] GetArtifactsToCleanup(ArtifactsPaths artifactsPaths) | ||
=> NeedsCopy | ||
? base.GetArtifactsToCleanup(artifactsPaths).Concat(new [] { CopyCoreRun.Directory.FullName }).ToArray() | ||
: base.GetArtifactsToCleanup(artifactsPaths); | ||
|
||
// source: https://stackoverflow.com/a/58779/5852046 | ||
private static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) | ||
{ | ||
if (!target.Exists) | ||
target.Create(); | ||
|
||
foreach (DirectoryInfo dir in source.GetDirectories()) | ||
CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name)); | ||
foreach (FileInfo file in source.GetFiles()) | ||
file.CopyTo(Path.Combine(target.FullName, file.Name)); | ||
} | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
src/BenchmarkDotNet/Toolchains/CoreRun/CoreRunPublisher.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Linq; | ||
using BenchmarkDotNet.Loggers; | ||
using BenchmarkDotNet.Running; | ||
using BenchmarkDotNet.Toolchains.DotNetCli; | ||
using BenchmarkDotNet.Toolchains.Results; | ||
|
||
namespace BenchmarkDotNet.Toolchains.CoreRun | ||
{ | ||
public class CoreRunPublisher : IBuilder | ||
{ | ||
public CoreRunPublisher(FileInfo coreRun, FileInfo customDotNetCliPath = null) | ||
{ | ||
CoreRun = coreRun; | ||
DotNetCliPublisher = new DotNetCliPublisher(customDotNetCliPath?.FullName); | ||
} | ||
|
||
private FileInfo CoreRun { get; } | ||
|
||
private DotNetCliPublisher DotNetCliPublisher { get; } | ||
|
||
public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger) | ||
{ | ||
var buildResult = DotNetCliPublisher.Build(generateResult, buildPartition, logger); | ||
|
||
if (buildResult.IsBuildSuccess) | ||
UpdateDuplicatedDependencies(buildResult.ArtifactsPaths, logger); | ||
|
||
return buildResult; | ||
} | ||
|
||
/// <summary> | ||
/// update CoreRun folder with newer versions of duplicated dependencies | ||
/// </summary> | ||
private void UpdateDuplicatedDependencies(ArtifactsPaths artifactsPaths, ILogger logger) | ||
{ | ||
var publishedDirectory = new DirectoryInfo(artifactsPaths.BinariesDirectoryPath); | ||
var coreRunDirectory = CoreRun.Directory; | ||
|
||
foreach (var publishedDependency in publishedDirectory | ||
.EnumerateFileSystemInfos() | ||
.Where(file => file.Extension == ".dll" || file.Extension == ".exe" )) | ||
{ | ||
var coreRunDependency = new FileInfo(Path.Combine(coreRunDirectory.FullName, publishedDependency.Name)); | ||
|
||
if (!coreRunDependency.Exists) | ||
continue; // the file does not exist in CoreRun directory, we don't need to worry, it will be just loaded from publish directory by CoreRun | ||
|
||
var publishedVersionInfo = FileVersionInfo.GetVersionInfo(publishedDependency.FullName); | ||
var coreRunVersionInfo = FileVersionInfo.GetVersionInfo(coreRunDependency.FullName); | ||
|
||
if(!Version.TryParse(publishedVersionInfo.FileVersion, out var publishedVersion) || !Version.TryParse(coreRunVersionInfo.FileVersion, out var coreRunVersion)) | ||
continue; | ||
|
||
if(publishedVersion > coreRunVersion) | ||
{ | ||
File.Copy(publishedDependency.FullName, coreRunDependency.FullName, overwrite: true); // we need to ovwerite old things with their newer versions | ||
|
||
logger.WriteLineInfo($"Copying {publishedDependency.FullName} to {coreRunDependency.FullName}"); | ||
} | ||
} | ||
} | ||
} | ||
} |
83 changes: 83 additions & 0 deletions
83
src/BenchmarkDotNet/Toolchains/CoreRun/CoreRunToolchain.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
using System; | ||
using System.IO; | ||
using BenchmarkDotNet.Characteristics; | ||
using BenchmarkDotNet.Environments; | ||
using BenchmarkDotNet.Extensions; | ||
using BenchmarkDotNet.Loggers; | ||
using BenchmarkDotNet.Running; | ||
using BenchmarkDotNet.Toolchains.DotNetCli; | ||
|
||
namespace BenchmarkDotNet.Toolchains.CoreRun | ||
{ | ||
public class CoreRunToolchain : IToolchain | ||
{ | ||
/// <summary> | ||
/// creates a CoreRunToolchain which is using provided CoreRun to execute .NET Core apps | ||
/// </summary> | ||
/// <param name="coreRun">the path to CoreRun</param> | ||
/// /<param name="createCopy">should a copy of CoreRun be performed? True by default. <remarks>The toolchain replaces old dependencies in CoreRun folder with newer versions if used by the benchmarks.</remarks></param> | ||
/// <param name="targetFrameworkMoniker">TFM, netcoreapp2.1 is the default</param> | ||
/// <param name="customDotNetCliPath">path to dotnet cli, if not provided the one from PATH will be used</param> | ||
/// <param name="displayName">display name, CoreRun is the default value</param> | ||
public CoreRunToolchain(FileInfo coreRun, bool createCopy = true, | ||
string targetFrameworkMoniker = "netcoreapp2.1", FileInfo customDotNetCliPath = null, | ||
string displayName = "CoreRun") | ||
{ | ||
if (coreRun == null) throw new ArgumentNullException(nameof(coreRun)); | ||
if (!coreRun.Exists) throw new FileNotFoundException("Povided CoreRun path does not exist"); | ||
|
||
SourceCoreRun = coreRun; | ||
CopyCoreRun = createCopy ? GetShadowCopyPath(coreRun) : coreRun; | ||
CustomDotNetCliPath = customDotNetCliPath; | ||
|
||
Name = displayName; | ||
Generator = new CoreRunGenerator(SourceCoreRun, CopyCoreRun, targetFrameworkMoniker, platform => platform.ToConfig()); | ||
Builder = new CoreRunPublisher(CopyCoreRun, customDotNetCliPath); | ||
Executor = new DotNetCliExecutor(customDotNetCliPath: CopyCoreRun.FullName); // instead of executing "dotnet $pathToDll" we do "CoreRun $pathToDll" | ||
} | ||
|
||
public string Name { get; } | ||
|
||
public IGenerator Generator { get; } | ||
|
||
public IBuilder Builder { get; } | ||
|
||
public IExecutor Executor { get; } | ||
|
||
public FileInfo SourceCoreRun { get; } | ||
|
||
public FileInfo CopyCoreRun { get; } | ||
|
||
public FileInfo CustomDotNetCliPath { get; } | ||
|
||
public override string ToString() => Name; | ||
|
||
public bool IsSupported(BenchmarkCase benchmark, ILogger logger, IResolver resolver) | ||
{ | ||
if (!SourceCoreRun.Exists) | ||
{ | ||
logger.WriteLineError($"Povided CoreRun path does not exist, benchmark '{benchmark.DisplayInfo}' will not be executed"); | ||
return false; | ||
} | ||
|
||
if (CustomDotNetCliPath == null && !HostEnvironmentInfo.GetCurrent().IsDotNetCliInstalled()) | ||
{ | ||
logger.WriteLineError($"BenchmarkDotNet requires dotnet cli toolchain to be installed, benchmark '{benchmark.DisplayInfo}' will not be executed"); | ||
return false; | ||
} | ||
|
||
if (CustomDotNetCliPath != null && !CustomDotNetCliPath.Exists) | ||
{ | ||
logger.WriteLineError($"Povided custom dotnet cli path does not exist, benchmark '{benchmark.DisplayInfo}' will not be executed"); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
private static FileInfo GetShadowCopyPath(FileInfo coreRunPath) | ||
=> coreRunPath.Directory.Parent != null | ||
? new FileInfo(Path.Combine(coreRunPath.Directory.Parent.FullName, Guid.NewGuid().ToString(), coreRunPath.Name)) | ||
: new FileInfo(Path.Combine(coreRunPath.Directory.FullName, Guid.NewGuid().ToString(), coreRunPath.Name)); // C:\CoreRun.exe case | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters