This is a combination of 18 commits which I squashed, the most important were: nice factory method for LocalCoreClr toolchain + removing filesToCopy (won't be needed anymore) don't use isolated nuget packages folder for non-local feeds update the tests projects to .NET Core 2.1 test nightly CoreFx builds support use --no-dependencies first, if it fails run the full mode restore and build in explicit way, let publish just publish /p:UseSharedCompilation=false by default to avoid zombie processes, run Core tests first (more likely to fail) remove old if defines that are no longer needed without .NET Core 1.1 support introduce builder for CustomCoreClrToolchain to make it easier to configure it print more diagnostic info, don't fail on first error and don't run the tests in parallel just run the self contained app without dotnet host add test for local CoreCLR and CoreFX builds, move them to a new project with can be run only manually allow to set RuntimeFrameworkVersion
This commit is contained in:
Родитель
bd04bdb655
Коммит
fcf69195b8
|
@ -37,6 +37,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarkDotNet.Disassemble
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarkDotNet.Disassembler.x86", "src\BenchmarkDotNet.Disassembler.x86\BenchmarkDotNet.Disassembler.x86.csproj", "{D189AAB3-46B4-4437-8E9C-72F021AB2B6E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkDotNet.IntegrationTests.ManualRunning", "tests\BenchmarkDotNet.IntegrationTests.ManualRunning\BenchmarkDotNet.IntegrationTests.ManualRunning.csproj", "{9816D316-95C4-42E6-9E7B-A256C7E5D4BF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -99,6 +101,10 @@ Global
|
|||
{D189AAB3-46B4-4437-8E9C-72F021AB2B6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D189AAB3-46B4-4437-8E9C-72F021AB2B6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D189AAB3-46B4-4437-8E9C-72F021AB2B6E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9816D316-95C4-42E6-9E7B-A256C7E5D4BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9816D316-95C4-42E6-9E7B-A256C7E5D4BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9816D316-95C4-42E6-9E7B-A256C7E5D4BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9816D316-95C4-42E6-9E7B-A256C7E5D4BF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -118,6 +124,7 @@ Global
|
|||
{043F1DA4-CD51-45FD-805E-6571D67AA661} = {14195214-591A-45B7-851A-19D3BA2413F9}
|
||||
{E5A0833C-B633-4D62-B645-A927CEBFEEBB} = {D6597E3A-6892-4A68-8E14-042FC941FDA2}
|
||||
{D189AAB3-46B4-4437-8E9C-72F021AB2B6E} = {D6597E3A-6892-4A68-8E14-042FC941FDA2}
|
||||
{9816D316-95C4-42E6-9E7B-A256C7E5D4BF} = {14195214-591A-45B7-851A-19D3BA2413F9}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {4D9AF12B-1F7F-45A7-9E8C-E4E46ADCBD1F}
|
||||
|
|
18
build.cake
18
build.cake
|
@ -26,6 +26,10 @@ Setup(_ =>
|
|||
Information("Build will use FrameworkPathOverride={0} since not building on Windows.", frameworkPathOverride);
|
||||
msBuildSettings.WithProperty("FrameworkPathOverride", frameworkPathOverride);
|
||||
}
|
||||
else
|
||||
{
|
||||
msBuildSettings.WithProperty("UseSharedCompilation", "false");
|
||||
}
|
||||
});
|
||||
|
||||
Task("Clean")
|
||||
|
@ -62,9 +66,9 @@ Task("FastTests")
|
|||
.Does(() =>
|
||||
{
|
||||
string[] targetVersions = IsRunningOnWindows() ?
|
||||
new []{"net46", "netcoreapp2.0"}
|
||||
new []{"net46", "netcoreapp2.1"}
|
||||
:
|
||||
new []{"netcoreapp2.0"};
|
||||
new []{"netcoreapp2.1"};
|
||||
|
||||
foreach(var version in targetVersions)
|
||||
{
|
||||
|
@ -85,7 +89,7 @@ Task("SlowTestsNetCore2")
|
|||
.WithCriteria(!skipTests)
|
||||
.Does(() =>
|
||||
{
|
||||
DotNetCoreTool(integrationTestsProjectPath, "xunit", GetTestSettingsParameters("netcoreapp2.0"));
|
||||
DotNetCoreTool(integrationTestsProjectPath, "xunit", GetTestSettingsParameters("netcoreapp2.1"));
|
||||
});
|
||||
|
||||
Task("Pack")
|
||||
|
@ -111,8 +115,8 @@ Task("Default")
|
|||
.IsDependentOn("Restore")
|
||||
.IsDependentOn("Build")
|
||||
.IsDependentOn("FastTests")
|
||||
.IsDependentOn("SlowTestsNet46")
|
||||
.IsDependentOn("SlowTestsNetCore2")
|
||||
.IsDependentOn("SlowTestsNet46")
|
||||
.IsDependentOn("Pack");
|
||||
|
||||
RunTarget(target);
|
||||
|
@ -120,10 +124,10 @@ RunTarget(target);
|
|||
// HELPERS
|
||||
private string GetTestSettingsParameters(string tfm)
|
||||
{
|
||||
var settings = $"-configuration {configuration} -stoponfail -maxthreads unlimited -nobuild -framework {tfm}";
|
||||
if(string.Equals("netcoreapp2.0", tfm, StringComparison.OrdinalIgnoreCase))
|
||||
var settings = $"-configuration {configuration} -parallel none -nobuild -framework {tfm}";
|
||||
if(string.Equals("netcoreapp2.1", tfm, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
settings += " --fx-version 2.0.6";
|
||||
settings += " --fx-version 2.1.0-preview1-26216-03";
|
||||
}
|
||||
|
||||
return settings;
|
||||
|
|
|
@ -32,7 +32,7 @@ Param(
|
|||
)
|
||||
|
||||
$CakeVersion = "0.26.1"
|
||||
$DotNetVersion = "2.1.101";
|
||||
$DotNetVersion = "2.1.300-preview1-008174";
|
||||
$DotNetInstallerUri = "https://dot.net/v1/dotnet-install.ps1";
|
||||
$NugetUrl = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
|
||||
|
||||
|
|
2
build.sh
2
build.sh
|
@ -47,7 +47,7 @@ if [ ! -d "$SCRIPT_DIR/.dotnet" ]; then
|
|||
mkdir "$SCRIPT_DIR/.dotnet"
|
||||
fi
|
||||
curl -Lsfo "$SCRIPT_DIR/.dotnet/dotnet-install.sh" https://dot.net/v1/dotnet-install.sh
|
||||
sudo bash "$SCRIPT_DIR/.dotnet/dotnet-install.sh" --version 2.1.101 --install-dir .dotnet --no-path
|
||||
sudo bash "$SCRIPT_DIR/.dotnet/dotnet-install.sh" --version 2.1.300-preview1-008174 --install-dir .dotnet --no-path
|
||||
export PATH="$SCRIPT_DIR/.dotnet":$PATH
|
||||
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
|
||||
export DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<PropertyGroup Condition=" '$(IsVisualBasic)' != 'true' And '$(TargetFramework)' == 'net46' ">
|
||||
<DefineConstants>$(DefineConstants);CLASSIC</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(IsVisualBasic)' != 'true' And '$(TargetFramework)' == 'netcoreapp2.0' ">
|
||||
<PropertyGroup Condition=" '$(IsVisualBasic)' != 'true' And ('$(TargetFramework)' == 'netcoreapp2.0' Or '$(TargetFramework)' == 'netcoreapp2.1') ">
|
||||
<DefineConstants>$(DefineConstants);CORE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -118,59 +118,63 @@ Jit=RyuJit
|
|||
|
||||
BenchmarkDotNet allows the users to run their benchmarks against ANY CoreCLR and CoreFX builds. You can compare your local build vs MyGet feed or Debug vs Release or one version vs another.
|
||||
|
||||
To avoid problems described [here](https://github.com/dotnet/coreclr/blob/master/Documentation/workflow/UsingDotNetCli.md#update-coreclr-using-runtime-nuget-package) a temporary folder is used when restoring packages for local builds. This is why it takes 20-30s in total to build the benchmarks.
|
||||
|
||||
Sample config:
|
||||
|
||||
```cs
|
||||
public class LocalCoreClrConfig : ManualConfig
|
||||
{
|
||||
public LocalCoreClrConfig()
|
||||
{
|
||||
Add(Job.ShortRun.With(
|
||||
new CustomCoreClrToolchain(
|
||||
"local builds",
|
||||
coreClrNuGetFeed: @"C:\Projects\forks\coreclr\bin\Product\Windows_NT.x64.Release\.nuget\pkg",
|
||||
coreClrVersion: "2.1.0-preview2-26313-0",
|
||||
coreFxNuGetFeed: @"C:\Projects\forks\corefx\bin\packages\Release",
|
||||
coreFxVersion: "4.5.0-preview2-26313-0")
|
||||
));
|
||||
public LocalCoreClrConfig()
|
||||
{
|
||||
Add(Job.ShortRun.With(
|
||||
CustomCoreClrToolchain.CreateBuilder()
|
||||
.DisplayName("local builds")
|
||||
.UseCoreClrLocalBuild("2.1.0-preview2-26313-0", @"C:\Projects\forks\coreclr\bin\Product\Windows_NT.x64.Release\.nuget\pkg", @"C:\Projects\coreclr\packages")
|
||||
.UseCoreFxLocalBuild("4.5.0-preview2-26313-0", @"C:\Projects\forks\corefx\bin\packages\Release")
|
||||
.ToToolchain()));
|
||||
|
||||
Add(Job.ShortRun.With(
|
||||
new CustomCoreClrToolchain(
|
||||
"local coreclr myget corefx",
|
||||
coreClrNuGetFeed: @"C:\Projects\forks\coreclr\bin\Product\Windows_NT.x64.Release\.nuget\pkg",
|
||||
coreClrVersion: "2.1.0-preview2-26313-0",
|
||||
coreFxNuGetFeed: "https://dotnet.myget.org/F/dotnet-core/api/v3/index.json",
|
||||
coreFxVersion: "4.5.0-preview2-26215-01")
|
||||
));
|
||||
Add(Job.ShortRun.With(
|
||||
CustomCoreClrToolchain.CreateBuilder()
|
||||
.DisplayName("local coreclr myget corefx")
|
||||
.UseCoreClrLocalBuild("2.1.0-preview2-26313-0", @"C:\Projects\forks\coreclr\bin\Product\Windows_NT.x64.Release\.nuget\pkg", @"C:\Projects\coreclr\packages")
|
||||
.UseCoreFxNuGet("4.5.0-preview2-26215-01")
|
||||
.ToToolchain()));
|
||||
|
||||
Add(Job.ShortRun.With(
|
||||
new CustomCoreClrToolchain(
|
||||
"myget coreclr local corefx",
|
||||
coreClrNuGetFeed: "https://dotnet.myget.org/F/dotnet-core/api/v3/index.json",
|
||||
coreClrVersion: "2.1.0-preview2-26214-07",
|
||||
coreFxNuGetFeed: @"C:\Projects\forks\corefx\bin\packages\Release",
|
||||
coreFxVersion: "4.5.0-preview2-26313-0")
|
||||
));
|
||||
Add(Job.ShortRun.With(
|
||||
CustomCoreClrToolchain.CreateBuilder()
|
||||
.DisplayName("myget coreclr local corefx")
|
||||
.UseCoreClrNuGet("2.1.0-preview2-26214-07")
|
||||
.UseCoreFxLocalBuild("4.5.0-preview2-26313-0", @"C:\Projects\forks\corefx\bin\packages\Release")
|
||||
.ToToolchain()));
|
||||
|
||||
Add(Job.ShortRun.With(
|
||||
new CustomCoreClrToolchain(
|
||||
"myget builds",
|
||||
coreClrNuGetFeed: "https://dotnet.myget.org/F/dotnet-core/api/v3/index.json",
|
||||
coreClrVersion: "2.1.0-preview2-26214-07",
|
||||
coreFxNuGetFeed: "https://dotnet.myget.org/F/dotnet-core/api/v3/index.json",
|
||||
coreFxVersion: "4.5.0-preview2-26215-01")
|
||||
));
|
||||
Add(Job.ShortRun.With(
|
||||
CustomCoreClrToolchain.CreateBuilder()
|
||||
.DisplayName("myget builds")
|
||||
.UseCoreClrNuGet("2.1.0-preview2-26214-07")
|
||||
.UseCoreFxNuGet("4.5.0-preview2-26215-01")
|
||||
.ToToolchain()));
|
||||
|
||||
Add(DefaultConfig.Instance.GetExporters().ToArray());
|
||||
Add(DefaultConfig.Instance.GetLoggers().ToArray());
|
||||
Add(DefaultConfig.Instance.GetColumnProviders().ToArray());
|
||||
|
||||
Add(DefaultConfig.Instance.GetExporters().ToArray());
|
||||
Add(DefaultConfig.Instance.GetLoggers().ToArray());
|
||||
Add(DefaultConfig.Instance.GetColumnProviders().ToArray());
|
||||
|
||||
Add(DisassemblyDiagnoser.Create(new DisassemblyDiagnoserConfig(printAsm: true, recursiveDepth: 2)));
|
||||
}
|
||||
Add(DisassemblyDiagnoser.Create(new DisassemblyDiagnoserConfig(printAsm: true, recursiveDepth: 2)));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `CustomCoreClrToolchainBuilder` offers some extra customization features for our power users:
|
||||
|
||||
* `UseCoreClrDefault()` tells the toolchain to use the default CoreClr (for given dotnet cli and moniker), emits no direct dependency to NETCore.Runtime.CoreCLR package
|
||||
* `UseCoreFxDefault()` tells the toolchain to use the default CoreFx (for given dotnet cli and moniker), emits no direct dependency to NetCore.App package
|
||||
* `UseNuGetClearTag(bool)` emits clear tag in the auto-generated NuGet.config file, by default true for local builds
|
||||
* `TargetFrameworkMoniker(string)` TFM, netcoreapp2.1 is the default
|
||||
* `DotNetCli(string)` if not provided, the one from PATH will be used
|
||||
* `RuntimeIdentifier(string)` if not provided, portable OS-arch will be used (example: "win-x64", "linux-x86")
|
||||
* `RuntimeFrameworkVersion(string)` optional, when set it's copied to the generated .csproj file
|
||||
* `UseTempFolderForRestore(bool)` restore to temp folder to keep your CI clean or install same package many times (perhaps with different content but same version number), by default true for local builds
|
||||
|
||||
To make sure that you are running against the expected version of CoreCLR and CoreFX you just need to check the CoreCLR and CoreFX version numbers in the output:
|
||||
|
||||
```
|
||||
|
@ -185,14 +189,6 @@ Frequency=2533308 Hz, Resolution=394.7408 ns, Timer=TSC
|
|||
Job-CTQFFQ : .NET Core ? (CoreCLR 4.6.26214.07, CoreFX 4.6.26313.0), 64bit RyuJIT
|
||||
```
|
||||
|
||||
To support two most common scenarios we provide following methods: `CreateForLocalCoreFxBuild` and `CreateForNightlyCoreFxBuild`. Both methods allow to target custom CoreFX builds running on the default installed .NET Runtime.
|
||||
|
||||
```cs
|
||||
CustomCoreClrToolchain.CreateForNightlyCoreFxBuild("4.5.0-preview2-26215-01");
|
||||
|
||||
CustomCoreClrToolchain.CreateForLocalCoreFxBuild(@"C:\Projects\forks\corefx\bin\packages\Release", "4.5.0-preview2-26313-0");
|
||||
``
|
||||
|
||||
## InProcessToolchain
|
||||
|
||||
InProcessToolchain is our toolchain which does not generate any new executable. It emits IL on the fly and runs it from within the process itself. It can be usefull if want to run the benchmarks very fast or if you want to run them for framework which we don't support. An example could be a local build of CoreCLR.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<Import Project="..\..\build\common.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyTitle>BenchmarkDotNet.Samples</AssemblyTitle>
|
||||
<TargetFrameworks>net46;netcoreapp2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net46;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
|
||||
<RuntimeIdentifiers Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' ">win7-x64;win7-x86;osx.10.10-x64;osx.10.11-x64;ubuntu.14.04-x64;ubuntu.16.04-x64;centos.7-x64;rhel.7.2-x64;debian.8-x64;fedora.23-x64;opensuse.13.2-x64</RuntimeIdentifiers>
|
||||
<RuntimeIdentifiers Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' ">win7-x64;win7-x86</RuntimeIdentifiers>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#if !NETCOREAPP1_1
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
|
||||
|
@ -22,4 +21,3 @@ namespace BenchmarkDotNet.Samples.Framework
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#if !NETCOREAPP1_1
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
|
||||
namespace BenchmarkDotNet.Samples.Framework
|
||||
|
@ -18,5 +17,4 @@ namespace BenchmarkDotNet.Samples.Framework
|
|||
return new StackTrace().GetFrame(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,96 +1,239 @@
|
|||
using BenchmarkDotNet.Toolchains.DotNetCli;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.DotNet.PlatformAbstractions;
|
||||
|
||||
namespace BenchmarkDotNet.Toolchains.CustomCoreClr
|
||||
{
|
||||
public class CustomCoreClrToolchain : Toolchain
|
||||
{
|
||||
/// <summary>
|
||||
/// creates toolchain which uses dotnet cli publish to generated self-contained app that references given CoreCLR and CoreFX
|
||||
/// </summary>
|
||||
/// <param name="displayName">the name of the toolchain to be displayed in results</param>
|
||||
/// <param name="coreClrNuGetFeed">path to folder for local CoreCLR builds, url to MyGet feed for previews of CoreCLR. Example: "C:\coreclr\bin\Product\Windows_NT.x64.Debug\.nuget\pkg"</param>
|
||||
/// <param name="coreClrVersion">the version of Microsoft.NETCore.Runtime which should be used. Example: "2.1.0-preview2-26305-0"</param>
|
||||
/// <param name="coreFxNuGetFeed">path to folder for local CoreFX builds, url to MyGet feed for previews of CoreFX. Example: "C:\Projects\forks\corefx\bin\packages\Debug"</param>
|
||||
/// <param name="coreFxVersion">the version of Microsoft.Private.CoreFx.NETCoreApp which should be used. Example: 4.5.0-preview2-26307-0</param>
|
||||
/// <param name="targetFrameworkMoniker">TFM, netcoreapp2.1 is the default</param>
|
||||
/// <param name="runtimeIdentifier">if not provided, portable OS-arch will be used (example: "win-x64", "linux-x86")</param>
|
||||
/// <param name="customDotNetCliPath">if not provided, the default will be used</param>
|
||||
/// <param name="filesToCopy">files that should be copied to the published self-contained app. </param>
|
||||
/// <returns></returns>
|
||||
public CustomCoreClrToolchain(
|
||||
string displayName,
|
||||
string coreClrNuGetFeed, string coreClrVersion,
|
||||
string coreFxNuGetFeed, string coreFxVersion,
|
||||
string targetFrameworkMoniker = "netcoreapp2.1",
|
||||
string runtimeIdentifier = null,
|
||||
string customDotNetCliPath = null,
|
||||
string[] filesToCopy = null)
|
||||
: base(displayName,
|
||||
new Generator(coreClrNuGetFeed, coreClrVersion, coreFxNuGetFeed, coreFxVersion, targetFrameworkMoniker, runtimeIdentifier),
|
||||
new Publisher(targetFrameworkMoniker, customDotNetCliPath, filesToCopy),
|
||||
new DotNetCliExecutor(customDotNetCliPath))
|
||||
internal CustomCoreClrToolchain(string displayName, string coreClrVersion, string coreFxVersion, string runtimeFrameworkVersion,
|
||||
string targetFrameworkMoniker, string runtimeIdentifier,
|
||||
string customDotNetCliPath,
|
||||
Dictionary<string, string> feeds, bool useNuGetClearTag, bool useTempFolderForRestore)
|
||||
: base(displayName,
|
||||
new Generator(coreClrVersion, coreFxVersion, runtimeFrameworkVersion, targetFrameworkMoniker, runtimeIdentifier, feeds, useNuGetClearTag, useTempFolderForRestore),
|
||||
new Publisher(customDotNetCliPath),
|
||||
new Executor())
|
||||
{
|
||||
}
|
||||
|
||||
public static CustomCoreClrToolchainBuilder CreateBuilder() => CustomCoreClrToolchainBuilder.Create();
|
||||
}
|
||||
|
||||
public class CustomCoreClrToolchainBuilder
|
||||
{
|
||||
public static CustomCoreClrToolchainBuilder Create() => new CustomCoreClrToolchainBuilder();
|
||||
|
||||
private string coreClrVersion, coreFxVersion;
|
||||
private string runtimeIdentifier, customDotNetCliPath;
|
||||
private string targetFrameworkMoniker = "netcoreapp2.1", displayName = "not set";
|
||||
private string runtimeFrameworkVersion;
|
||||
|
||||
private bool isCoreClrConfigured = false, isCoreFxConfigured = false;
|
||||
private bool useNuGetClearTag = false, useTempFolderForRestore = false;
|
||||
|
||||
private Dictionary<string, string> feeds = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// creates a toolchain which publishes self-contained app which references local CoreClr build
|
||||
/// as described here https://github.com/dotnet/coreclr/blob/master/Documentation/workflow/UsingDotNetCli.md
|
||||
/// </summary>
|
||||
/// <param name="coreClrVersion">the version of Microsoft.NETCore.Runtime which should be used. Example: "2.1.0-preview2-26305-0"</param>
|
||||
/// <param name="binPackagesPath">path to folder with CoreClr NuGet packages. Example: "C:\coreclr\bin\Product\Windows_NT.x64.Release\.nuget\pkg"</param>
|
||||
/// <param name="packagesPath">path to folder with NuGet packages restored for CoreClr build. Example: "C:\Projects\coreclr\packages"</param>
|
||||
public CustomCoreClrToolchainBuilder UseCoreClrLocalBuild(string coreClrVersion, string binPackagesPath, string packagesPath)
|
||||
{
|
||||
if (coreClrVersion == null) throw new ArgumentNullException(nameof(coreClrVersion));
|
||||
if (binPackagesPath == null) throw new ArgumentNullException(nameof(binPackagesPath));
|
||||
if (!Directory.Exists(binPackagesPath)) throw new DirectoryNotFoundException($"{binPackagesPath} does not exist");
|
||||
if (packagesPath == null) throw new ArgumentNullException(nameof(packagesPath));
|
||||
if (!Directory.Exists(packagesPath)) throw new DirectoryNotFoundException($"{packagesPath} does not exist");
|
||||
|
||||
this.coreClrVersion = coreClrVersion;
|
||||
|
||||
feeds[Generator.LocalCoreClrPackagesBin] = binPackagesPath;
|
||||
feeds[Generator.LocalCoreClrPackages] = packagesPath;
|
||||
|
||||
isCoreClrConfigured = true;
|
||||
useNuGetClearTag = true;
|
||||
useTempFolderForRestore = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// creates a toolchain which publishes self-contained app which references NuGet CoreClr package
|
||||
/// </summary>
|
||||
/// <param name="coreClrVersion">the version of Microsoft.NETCore.Runtime which should be used. Example: "2.1.0-preview2-26305-0"</param>
|
||||
/// <param name="nugetFeedUrl">url to NuGet CoreCLR feed, The default is: "https://dotnet.myget.org/F/dotnet-core/api/v3/index.json"</param>
|
||||
public CustomCoreClrToolchainBuilder UseCoreClrNuGet(string coreClrVersion, string nugetFeedUrl = "https://dotnet.myget.org/F/dotnet-core/api/v3/index.json")
|
||||
{
|
||||
if (coreClrVersion == null) throw new ArgumentNullException(nameof(coreClrVersion));
|
||||
if (nugetFeedUrl == null) throw new ArgumentNullException(nameof(nugetFeedUrl));
|
||||
|
||||
this.coreClrVersion = coreClrVersion;
|
||||
|
||||
feeds[Generator.CoreClrNuGetFeed] = nugetFeedUrl;
|
||||
|
||||
isCoreClrConfigured = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// tells the toolchain to use the default CoreClr (for given dotnet cli and moniker), emits no direct dependency to NETCore.Runtime.CoreCLR package
|
||||
/// </summary>
|
||||
public CustomCoreClrToolchainBuilder UseCoreClrDefault()
|
||||
{
|
||||
isCoreClrConfigured = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// creates a toolchain which publishes self-contained app which references local CoreFx build
|
||||
/// as described here https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/dogfooding.md#more-advanced-scenario---using-your-local-corefx-build
|
||||
/// </summary>
|
||||
/// <param name="pathToNuGetFolder">path to folder with CoreFX NuGet packages, Example: "C:\Projects\forks\corefx\bin\packages\Release"</param>
|
||||
/// <param name="privateCoreFxNetCoreAppVersion">the version of Microsoft.Private.CoreFx.NETCoreApp which should be used. Example: "4.5.0-preview2-26307-0"</param>
|
||||
/// <param name="targetFrameworkMoniker">TFM, netcoreapp2.1 is the default</param>
|
||||
/// <param name="runtimeIdentifier">if not provided, portable OS-arch will be used (example: "win-x64", "linux-x86")</param>
|
||||
/// <param name="customDotNetCliPath">if not provided, the default will be used</param>
|
||||
/// <param name="displayName">the name of the toolchain to be displayed in results, the default is "localCoreFX"</param>
|
||||
/// <param name="filesToCopy">files that should be copied to the published self-contained app.
|
||||
/// If you don't want to rebuild entire CoreFX then just provide the paths to files which you have changed here</param>
|
||||
/// <returns></returns>
|
||||
public static IToolchain CreateForLocalCoreFxBuild(string pathToNuGetFolder, string privateCoreFxNetCoreAppVersion,
|
||||
string targetFrameworkMoniker = "netcoreapp2.1", string displayName = "localCoreFX", string runtimeIdentifier = null, string customDotNetCliPath = null,
|
||||
string[] filesToCopy = null)
|
||||
/// <param name="binPackagesPath">path to folder with CoreFX NuGet packages, Example: "C:\Projects\forks\corefx\bin\packages\Release"</param>
|
||||
public CustomCoreClrToolchainBuilder UseCoreFxLocalBuild(string privateCoreFxNetCoreAppVersion, string binPackagesPath)
|
||||
{
|
||||
if (!Directory.Exists(pathToNuGetFolder))
|
||||
throw new ArgumentException($"Directory {pathToNuGetFolder} does not exist");
|
||||
if (privateCoreFxNetCoreAppVersion == null) throw new ArgumentNullException(nameof(privateCoreFxNetCoreAppVersion));
|
||||
if (binPackagesPath == null) throw new ArgumentNullException(nameof(binPackagesPath));
|
||||
if (!Directory.Exists(binPackagesPath)) throw new DirectoryNotFoundException($"{binPackagesPath} does not exist");
|
||||
|
||||
runtimeIdentifier = runtimeIdentifier ?? CustomCoreClr.Generator.GetPortableRuntimeIdentifier();
|
||||
this.coreFxVersion = privateCoreFxNetCoreAppVersion;
|
||||
feeds[Generator.LocalCoreFxPacakgesBin] = binPackagesPath;
|
||||
isCoreFxConfigured = true;
|
||||
useTempFolderForRestore = true;
|
||||
|
||||
var expectedPackageFileName = $"runtime.{runtimeIdentifier}.Microsoft.Private.CoreFx.NETCoreApp.{privateCoreFxNetCoreAppVersion}.nupkg";
|
||||
if (!File.Exists(Path.Combine(pathToNuGetFolder, expectedPackageFileName)))
|
||||
throw new ArgumentException($"Expected package {expectedPackageFileName} was not found in {pathToNuGetFolder}. Please make sure you have provided the right version number");
|
||||
|
||||
if (filesToCopy != null)
|
||||
foreach (var fileToCopy in filesToCopy)
|
||||
if (!File.Exists(fileToCopy))
|
||||
throw new ArgumentException($"File {fileToCopy} does not exist!");
|
||||
|
||||
return new CustomCoreClrToolchain(displayName, null, null, pathToNuGetFolder, privateCoreFxNetCoreAppVersion, targetFrameworkMoniker, runtimeIdentifier, customDotNetCliPath, filesToCopy);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// creates a toolchain which publishes self-contained app which references nightly CoreFx build
|
||||
/// as described here https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/dogfooding.md#advanced-scenario---using-a-nightly-build-of-microsoftnetcoreapp
|
||||
/// creates a toolchain which publishes self-contained app which references NuGet CoreFx build
|
||||
/// </summary>
|
||||
/// <param name="privateCoreFxNetCoreAppVersion">the version of Microsoft.Private.CoreFx.NETCoreApp which should be used. Example: "4.5.0-preview2-26307-0"</param>
|
||||
/// <param name="nugetFeedUrl">ulr to NuGet CoreFX feed, The default is: "https://dotnet.myget.org/F/dotnet-core/api/v3/index.json"</param>
|
||||
/// <param name="targetFrameworkMoniker">TFM, netcoreapp2.1 is the default</param>
|
||||
/// <param name="runtimeIdentifier">if not provided, portable OS-arch will be used (example: "win-x64", "linux-x86")</param>
|
||||
/// <param name="customDotNetCliPath">if not provided, the default will be used</param>
|
||||
/// <param name="displayName">the name of the toolchain to be displayed in results, the default is "nightlyCoreFX"</param>
|
||||
/// <returns></returns>
|
||||
public static IToolchain CreateForNightlyCoreFxBuild(string privateCoreFxNetCoreAppVersion,
|
||||
string nugetFeedUrl = "https://dotnet.myget.org/F/dotnet-core/api/v3/index.json",
|
||||
string targetFrameworkMoniker = "netcoreapp2.1", string displayName = "nightlyCoreFX", string runtimeIdentifier = null, string customDotNetCliPath = null)
|
||||
public CustomCoreClrToolchainBuilder UseCoreFxNuGet(string privateCoreFxNetCoreAppVersion, string nugetFeedUrl = "https://dotnet.myget.org/F/dotnet-core/api/v3/index.json")
|
||||
{
|
||||
if (string.IsNullOrEmpty(privateCoreFxNetCoreAppVersion))
|
||||
throw new ArgumentNullException(nameof(privateCoreFxNetCoreAppVersion));
|
||||
if (string.IsNullOrEmpty(nugetFeedUrl))
|
||||
throw new ArgumentNullException(nameof(nugetFeedUrl));
|
||||
if (privateCoreFxNetCoreAppVersion == null) throw new ArgumentNullException(nameof(privateCoreFxNetCoreAppVersion));
|
||||
if (nugetFeedUrl == null) throw new ArgumentNullException(nameof(nugetFeedUrl));
|
||||
|
||||
runtimeIdentifier = runtimeIdentifier ?? CustomCoreClr.Generator.GetPortableRuntimeIdentifier();
|
||||
coreFxVersion = privateCoreFxNetCoreAppVersion;
|
||||
feeds[Generator.CoreFxNuGetFeed] = nugetFeedUrl;
|
||||
isCoreFxConfigured = true;
|
||||
|
||||
return new CustomCoreClrToolchain(displayName, null, null, nugetFeedUrl, privateCoreFxNetCoreAppVersion, targetFrameworkMoniker, runtimeIdentifier, customDotNetCliPath);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// tells the toolchain to use the default CoreFx (for given dotnet cli and moniker), emits no direct dependency to NetCore.App package
|
||||
/// </summary>
|
||||
public CustomCoreClrToolchainBuilder UseCoreFxDefault()
|
||||
{
|
||||
isCoreFxConfigured = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// emits clear tag in the auto-generated NuGet.config file, by default true for local builds
|
||||
/// </summary>
|
||||
public CustomCoreClrToolchainBuilder UseNuGetClearTag(bool value)
|
||||
{
|
||||
useNuGetClearTag = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <param name="targetFrameworkMoniker">TFM, netcoreapp2.1 is the default</param>
|
||||
public CustomCoreClrToolchainBuilder TargetFrameworkMoniker(string targetFrameworkMoniker = "netcoreapp2.1")
|
||||
{
|
||||
this.targetFrameworkMoniker = targetFrameworkMoniker ?? throw new ArgumentNullException(nameof(targetFrameworkMoniker));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <param name="customDotNetCliPath">if not provided, the one from PATH will be used</param>
|
||||
public CustomCoreClrToolchainBuilder DotNetCli(string customDotNetCliPath)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(customDotNetCliPath) && !File.Exists(customDotNetCliPath))
|
||||
throw new FileNotFoundException("Given file does not exist", customDotNetCliPath);
|
||||
|
||||
this.customDotNetCliPath = customDotNetCliPath;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <param name="runtimeIdentifier">if not provided, portable OS-arch will be used (example: "win-x64", "linux-x86")</param>
|
||||
public CustomCoreClrToolchainBuilder RuntimeIdentifier(string runtimeIdentifier)
|
||||
{
|
||||
this.runtimeIdentifier = runtimeIdentifier;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <param name="runtimeFrameworkVersion">optional, when set it's copied to the generated .csproj file</param>
|
||||
public CustomCoreClrToolchainBuilder RuntimeFrameworkVersion(string runtimeFrameworkVersion)
|
||||
{
|
||||
this.runtimeFrameworkVersion = runtimeFrameworkVersion;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <param name="displayName">the name of the toolchain to be displayed in results</param>
|
||||
public CustomCoreClrToolchainBuilder DisplayName(string displayName)
|
||||
{
|
||||
if (String.IsNullOrEmpty(displayName)) throw new ArgumentException("Value cannot be null or empty.", nameof(displayName));
|
||||
|
||||
this.displayName = displayName;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// restore to temp folder to keep your CI clean or install same package many times (perhaps with different content but same version number), by default true for local builds
|
||||
/// https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/dogfooding.md#3---consuming-subsequent-code-changes-by-rebuilding-the-package-alternative-2
|
||||
/// </summary>
|
||||
public CustomCoreClrToolchainBuilder UseTempFolderForRestore(bool value)
|
||||
{
|
||||
useTempFolderForRestore = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public IToolchain ToToolchain()
|
||||
{
|
||||
if (!isCoreClrConfigured)
|
||||
throw new InvalidOperationException("You need to use one of the UseCoreClr* methods to tell us which CoreClr to use.");
|
||||
|
||||
if (!isCoreFxConfigured)
|
||||
throw new InvalidOperationException("You need to use one of the UseCoreFx* methods to tell us which CoreFx to use.");
|
||||
|
||||
return new CustomCoreClrToolchain(
|
||||
displayName: displayName,
|
||||
coreClrVersion: coreClrVersion,
|
||||
coreFxVersion: coreFxVersion,
|
||||
runtimeFrameworkVersion: runtimeFrameworkVersion,
|
||||
targetFrameworkMoniker: targetFrameworkMoniker,
|
||||
runtimeIdentifier: runtimeIdentifier ?? GetPortableRuntimeIdentifier(),
|
||||
customDotNetCliPath: customDotNetCliPath,
|
||||
feeds: feeds,
|
||||
useNuGetClearTag: useNuGetClearTag,
|
||||
useTempFolderForRestore: useTempFolderForRestore);
|
||||
}
|
||||
|
||||
private static string GetPortableRuntimeIdentifier()
|
||||
{
|
||||
// Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.GetRuntimeIdentifier()
|
||||
// returns win10-x64, we want the simpler form win-x64
|
||||
// the values taken from https://docs.microsoft.com/en-us/dotnet/core/rid-catalog#macos-rids
|
||||
string osPart = RuntimeEnvironment.OperatingSystemPlatform == Platform.Windows
|
||||
? "win" : (RuntimeEnvironment.OperatingSystemPlatform == Platform.Linux ? "linux" : "osx");
|
||||
|
||||
return $"{osPart}-{RuntimeEnvironment.RuntimeArchitecture}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,76 +1,91 @@
|
|||
using BenchmarkDotNet.Loggers;
|
||||
using BenchmarkDotNet.Running;
|
||||
using BenchmarkDotNet.Toolchains.CsProj;
|
||||
using Microsoft.DotNet.PlatformAbstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BenchmarkDotNet.Extensions;
|
||||
using BenchmarkDotNet.Portability;
|
||||
|
||||
namespace BenchmarkDotNet.Toolchains.CustomCoreClr
|
||||
{
|
||||
/// <summary>
|
||||
/// generates new csproj file for self-contained .NET Core app which uses local/preview CoreCLR build
|
||||
/// generates new csproj file for self-contained .NET Core app which uses given CoreCLR NuGet packages
|
||||
/// based on https://github.com/dotnet/coreclr/blob/master/Documentation/workflow/UsingDotNetCli.md and https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/dogfooding.md
|
||||
/// </summary>
|
||||
public class Generator : CsProjGenerator
|
||||
{
|
||||
/// <param name="coreClrNuGetFeed">path to folder for local CoreCLR builds, url to MyGet feed for previews of CoreCLR. Example: "C:\coreclr\bin\Product\Windows_NT.x64.Debug\.nuget\pkg"</param>
|
||||
/// <param name="coreClrVersion">the version of Microsoft.NETCore.Runtime which should be used. Example: "2.1.0-preview2-26305-0"</param>
|
||||
/// <param name="coreFxNuGetFeed">path to folder for local CoreFX builds, url to MyGet feed for previews of CoreFX. Example: "C:\Projects\forks\corefx\bin\packages\Debug"</param>
|
||||
/// <param name="coreFxVersion">the version of Microsoft.Private.CoreFx.NETCoreApp which should be used. Example: 4.5.0-preview2-26307-0</param>
|
||||
/// <param name="targetFrameworkMoniker">TFM, netcoreapp2.1 is the default</param>
|
||||
/// <param name="runtimeIdentifier">if not provided, portable OS-arch will be used (example: "win-x64", "linux-x86")</param>
|
||||
public Generator(string coreClrNuGetFeed, string coreClrVersion,
|
||||
string coreFxNuGetFeed, string coreFxVersion,
|
||||
string targetFrameworkMoniker = "netcoreapp2.1",
|
||||
string runtimeIdentifier = null)
|
||||
: base(targetFrameworkMoniker, platform => platform.ToString())
|
||||
{
|
||||
if (!((!string.IsNullOrEmpty(coreClrNuGetFeed) && !string.IsNullOrEmpty(coreClrVersion))
|
||||
|| (!string.IsNullOrEmpty(coreFxNuGetFeed) && !string.IsNullOrEmpty(coreFxVersion))))
|
||||
throw new ArgumentNullException("At least one thing (CLR/FX) has to be configured");
|
||||
internal const string LocalCoreClrPackagesBin = "localCoreClrPackagesBin";
|
||||
internal const string LocalCoreClrPackages = "localCoreClrPackages";
|
||||
internal const string CoreClrNuGetFeed = "coreClrNuGetFeed";
|
||||
internal const string LocalCoreFxPacakgesBin = "localCoreFxPacakgesBin";
|
||||
internal const string CoreFxNuGetFeed = "coreFxNuGetFeed";
|
||||
|
||||
CoreClrNuGetFeed = coreClrNuGetFeed;
|
||||
CoreClrVersion = coreClrVersion;
|
||||
CoreFxNuGetFeed = coreFxNuGetFeed;
|
||||
CoreFxVersion = coreFxVersion;
|
||||
RuntimeIdentifier = runtimeIdentifier ?? GetPortableRuntimeIdentifier();
|
||||
internal Generator(string coreClrVersion, string coreFxVersion, string runtimeFrameworkVersion, string targetFrameworkMoniker, string runtimeIdentifier, IReadOnlyDictionary<string, string> feeds, bool useNuGetClearTag, bool useTempFolderForRestore)
|
||||
: base(targetFrameworkMoniker, platfrom => platfrom.ToConfig(), runtimeFrameworkVersion)
|
||||
{
|
||||
this.coreClrVersion = coreClrVersion;
|
||||
this.coreFxVersion = coreFxVersion;
|
||||
this.targetFrameworkMoniker = targetFrameworkMoniker;
|
||||
this.runtimeIdentifier = runtimeIdentifier;
|
||||
this.feeds = feeds;
|
||||
this.useNuGetClearTag = useNuGetClearTag;
|
||||
this.useTempFolderForRestore = useTempFolderForRestore;
|
||||
}
|
||||
|
||||
private string CoreClrNuGetFeed { get; }
|
||||
private string CoreClrVersion { get; }
|
||||
private string CoreFxNuGetFeed { get; }
|
||||
private string CoreFxVersion { get; }
|
||||
private string RuntimeIdentifier { get; }
|
||||
private readonly string coreClrVersion;
|
||||
private readonly string coreFxVersion;
|
||||
private readonly string targetFrameworkMoniker;
|
||||
private readonly string runtimeIdentifier;
|
||||
private readonly IReadOnlyDictionary<string, string> feeds;
|
||||
private readonly bool useNuGetClearTag;
|
||||
private readonly bool useTempFolderForRestore;
|
||||
|
||||
private bool IsUsingCustomCoreClr => !string.IsNullOrEmpty(CoreClrNuGetFeed) && !string.IsNullOrEmpty(CoreClrVersion);
|
||||
private bool IsUsingCustomCoreFx => !string.IsNullOrEmpty(CoreFxNuGetFeed) && !string.IsNullOrEmpty(CoreFxVersion);
|
||||
private bool IsUsingCustomCoreClr => feeds.ContainsKey(LocalCoreClrPackagesBin) || feeds.ContainsKey(CoreClrNuGetFeed);
|
||||
private bool IsUsingCustomCoreFx => feeds.ContainsKey(LocalCoreFxPacakgesBin) || feeds.ContainsKey(CoreFxNuGetFeed);
|
||||
|
||||
private bool IsLocalCoreClr => IsUsingCustomCoreClr && Directory.Exists(CoreClrNuGetFeed);
|
||||
private bool IsLocalCoreFx => IsUsingCustomCoreFx && Directory.Exists(CoreFxNuGetFeed);
|
||||
private bool IsLocalCoreClr => feeds.ContainsKey(LocalCoreClrPackagesBin);
|
||||
private bool IsLocalCoreFx => feeds.ContainsKey(LocalCoreFxPacakgesBin);
|
||||
|
||||
protected override string GetExecutableExtension() => RuntimeInformation.ExecutableExtension;
|
||||
|
||||
protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName)
|
||||
=> Path.Combine(Path.GetTempPath(), programName); // store everything in temp to avoid collisions with IDE
|
||||
=> useTempFolderForRestore
|
||||
? Path.Combine(Path.GetTempPath(), programName) // store everything in temp to avoid collisions with IDE
|
||||
: base.GetBuildArtifactsDirectoryPath(buildPartition, programName);
|
||||
|
||||
protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)
|
||||
=> Path.Combine(buildArtifactsDirectoryPath, "bin", configuration, TargetFrameworkMoniker, RuntimeIdentifier, "publish");
|
||||
=> Path.Combine(buildArtifactsDirectoryPath, "bin", configuration, TargetFrameworkMoniker, runtimeIdentifier);
|
||||
|
||||
protected override void GenerateBuildScript(BuildPartition buildPartition, ArtifactsPaths artifactsPaths)
|
||||
=> File.WriteAllText(artifactsPaths.BuildScriptFilePath,
|
||||
$"dotnet restore --packages {artifactsPaths.PackagesDirectoryName} --no-dependencies" + Environment.NewLine +
|
||||
$"dotnet build -c {buildPartition.BuildConfiguration} --no-restore --no-dependencies" + Environment.NewLine +
|
||||
$"dotnet publish -c {buildPartition.BuildConfiguration} --no-restore --no-dependencies");
|
||||
{
|
||||
if (useTempFolderForRestore)
|
||||
{
|
||||
File.WriteAllText(artifactsPaths.BuildScriptFilePath,
|
||||
$"dotnet restore --packages {artifactsPaths.PackagesDirectoryName} --no-dependencies" + Environment.NewLine +
|
||||
$"dotnet build -c {buildPartition.BuildConfiguration} --no-restore --no-dependencies" + Environment.NewLine +
|
||||
$"dotnet publish -c {buildPartition.BuildConfiguration} --no-restore --no-dependencies");
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText(artifactsPaths.BuildScriptFilePath, $"dotnet publish -c {buildPartition.BuildConfiguration}");
|
||||
}
|
||||
}
|
||||
|
||||
// we always want to have a new directory for NuGet packages restore
|
||||
// to avoid this https://github.com/dotnet/coreclr/blob/master/Documentation/workflow/UsingDotNetCli.md#update-coreclr-using-runtime-nuget-package
|
||||
// some of the packages are going to contain source code, so they can not be in the subfolder of current solution
|
||||
// otherwise they would be compiled too (new .csproj include all .cs files from subfolders by default
|
||||
protected override string GetPackagesDirectoryPath(string buildArtifactsDirectoryPath)
|
||||
=> Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
=> useTempFolderForRestore
|
||||
? Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())
|
||||
: null;
|
||||
|
||||
protected override string[] GetArtifactsToCleanup(ArtifactsPaths artifactsPaths)
|
||||
=> base.GetArtifactsToCleanup(artifactsPaths).Concat(new[] { artifactsPaths.PackagesDirectoryName }).ToArray();
|
||||
=> useTempFolderForRestore
|
||||
? base.GetArtifactsToCleanup(artifactsPaths).Concat(new[] { artifactsPaths.PackagesDirectoryName }).ToArray()
|
||||
: base.GetArtifactsToCleanup(artifactsPaths);
|
||||
|
||||
protected override void GenerateNuGetConfig(ArtifactsPaths artifactsPaths)
|
||||
{
|
||||
|
@ -78,8 +93,8 @@ namespace BenchmarkDotNet.Toolchains.CustomCoreClr
|
|||
$@"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key=""{nameof(CoreClrNuGetFeed)}"" value=""{CoreClrNuGetFeed}"" />
|
||||
<add key=""{nameof(CoreFxNuGetFeed)}"" value=""{CoreFxNuGetFeed}"" />
|
||||
{(useNuGetClearTag ? "<clear/>" : string.Empty)}
|
||||
{string.Join(Environment.NewLine + " ", feeds.Select(feed => $"<add key=\"{feed.Key}\" value=\"{feed.Value}\" />"))}
|
||||
</packageSources>
|
||||
</configuration>";
|
||||
|
||||
|
@ -93,14 +108,15 @@ $@"<?xml version=""1.0"" encoding=""utf-8""?>
|
|||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>{TargetFrameworkMoniker}</TargetFramework>
|
||||
<RuntimeIdentifier>{RuntimeIdentifier}</RuntimeIdentifier>
|
||||
<RuntimeIdentifier>{runtimeIdentifier}</RuntimeIdentifier>
|
||||
<RuntimeFrameworkVersion>{RuntimeFrameworkVersion}</RuntimeFrameworkVersion>
|
||||
<AssemblyName>{artifactsPaths.ProgramName}</AssemblyName>
|
||||
<AssemblyTitle>{artifactsPaths.ProgramName}</AssemblyTitle>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<PackageConflictPreferredPackages>Microsoft.Private.CoreFx.NETCoreApp;runtime.{RuntimeIdentifier}.Microsoft.Private.CoreFx.NETCoreApp;Microsoft.NETCore.App;$(PackageConflictPreferredPackages)</PackageConflictPreferredPackages>
|
||||
<PackageConflictPreferredPackages>runtime.{runtimeIdentifier}.Microsoft.NETCore.Runtime.CoreCLR;runtime.{runtimeIdentifier}.Microsoft.NETCore.Jit;runtime.{runtimeIdentifier}.Microsoft.Private.CoreFx.NETCoreApp;Microsoft.Private.CoreFx.NETCoreApp;Microsoft.NETCore.App;$(PackageConflictPreferredPackages)</PackageConflictPreferredPackages>
|
||||
</PropertyGroup>
|
||||
{GetRuntimeSettings(buildPartition.RepresentativeBenchmark.Job.Env.Gc, buildPartition.Resolver)}
|
||||
<ItemGroup>
|
||||
|
@ -118,29 +134,16 @@ $@"<?xml version=""1.0"" encoding=""utf-8""?>
|
|||
{
|
||||
if (IsUsingCustomCoreClr)
|
||||
{
|
||||
var coreClrPackagesPrefix = IsLocalCoreClr ? $"runtime.{RuntimeIdentifier}." : null;
|
||||
yield return $@"<PackageReference Include=""{coreClrPackagesPrefix}Microsoft.NETCore.Runtime.CoreCLR"" Version=""{CoreClrVersion}"" />";
|
||||
yield return $@"<PackageReference Include=""{coreClrPackagesPrefix}Microsoft.NETCore.Jit"" Version=""{CoreClrVersion}"" />";
|
||||
yield return $@"<PackageReference Include=""runtime.{runtimeIdentifier}.Microsoft.NETCore.Runtime.CoreCLR"" Version=""{coreClrVersion}"" />";
|
||||
yield return $@"<PackageReference Include=""runtime.{runtimeIdentifier}.Microsoft.NETCore.Jit"" Version=""{coreClrVersion}"" />";
|
||||
}
|
||||
|
||||
if (IsUsingCustomCoreFx)
|
||||
{
|
||||
var coreFxPackagesPrefix = IsLocalCoreFx ? $"runtime.{RuntimeIdentifier}." : null;
|
||||
yield return $@"<PackageReference Include=""{coreFxPackagesPrefix}Microsoft.Private.CoreFx.NETCoreApp"" Version=""{CoreFxVersion}"" />";
|
||||
yield return $@"<PackageReference Include=""runtime.{runtimeIdentifier}.Microsoft.Private.CoreFx.NETCoreApp"" Version=""{coreFxVersion}"" />";
|
||||
}
|
||||
|
||||
yield return $@"<ProjectReference Include=""{GetProjectFilePath(benchmark.Target.Type, logger).FullName}"" />";
|
||||
}
|
||||
|
||||
internal static string GetPortableRuntimeIdentifier()
|
||||
{
|
||||
// Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.GetRuntimeIdentifier()
|
||||
// returns win10-x64, we want the simpler form win-x64
|
||||
// the values taken from https://docs.microsoft.com/en-us/dotnet/core/rid-catalog#macos-rids
|
||||
string osPart = RuntimeEnvironment.OperatingSystemPlatform == Platform.Windows
|
||||
? "win" : (RuntimeEnvironment.OperatingSystemPlatform == Platform.Linux ? "linux" : "osx");
|
||||
|
||||
return $"{osPart}-{RuntimeEnvironment.RuntimeArchitecture}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
using BenchmarkDotNet.Characteristics;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using BenchmarkDotNet.Loggers;
|
||||
using BenchmarkDotNet.Running;
|
||||
using BenchmarkDotNet.Toolchains.DotNetCli;
|
||||
|
@ -11,21 +9,28 @@ namespace BenchmarkDotNet.Toolchains.CustomCoreClr
|
|||
{
|
||||
public class Publisher : IBuilder
|
||||
{
|
||||
public Publisher(string targetFrameworkMoniker, string customDotNetCliPath = null, string[] filesToCopy = null)
|
||||
{
|
||||
TargetFrameworkMoniker = targetFrameworkMoniker;
|
||||
CustomDotNetCliPath = customDotNetCliPath;
|
||||
FilesToCopy = filesToCopy;
|
||||
}
|
||||
public Publisher(string customDotNetCliPath = null) => CustomDotNetCliPath = customDotNetCliPath;
|
||||
|
||||
private string TargetFrameworkMoniker { get; }
|
||||
private string CustomDotNetCliPath { get; }
|
||||
private string[] FilesToCopy { get; }
|
||||
|
||||
public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)
|
||||
{
|
||||
var extraArguments = DotNetCliGenerator.GetCustomArguments(buildPartition.RepresentativeBenchmark, buildPartition.Resolver);
|
||||
|
||||
var publishNoDependencies = CheckResult(generateResult, Build(generateResult, buildPartition, logger, $"--no-dependencies {extraArguments}"));
|
||||
|
||||
// at first we try to build the project without it's dependencies to save a LOT of time
|
||||
// in 99% of the cases it will work (the host process is running so something can be compiled!)
|
||||
if (publishNoDependencies.IsBuildSuccess)
|
||||
return publishNoDependencies;
|
||||
|
||||
return CheckResult(generateResult, Build(generateResult, buildPartition, logger, extraArguments));
|
||||
}
|
||||
|
||||
private DotNetCliCommandExecutor.CommandResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger, string extraArguments)
|
||||
{
|
||||
bool needsIsolatedFolderForRestore = !string.IsNullOrEmpty(generateResult.ArtifactsPaths.PackagesDirectoryName);
|
||||
|
||||
// restore --packages restores all packages to a dedicated folder, our Generator always creates a new folder for this in temp (see Generator.GetPackagesDirectoryPath())
|
||||
// it's mandatory for us for two reasons:
|
||||
// 1. dotnet restore installs given package with given version number only once (every next restore reuses that package)
|
||||
|
@ -40,49 +45,37 @@ namespace BenchmarkDotNet.Toolchains.CustomCoreClr
|
|||
// it's a sign for the tool that everything needs to be rebuild. Including the project that is currently executing!!
|
||||
// So by using this switch we use existing dlls and just build the auto-generated project
|
||||
// without this we would be trying to rebuild project which is currently in use and we would be getting file in use exceptions..
|
||||
|
||||
var restoreResult = DotNetCliCommandExecutor.ExecuteCommand(
|
||||
CustomDotNetCliPath,
|
||||
$"restore --packages {generateResult.ArtifactsPaths.PackagesDirectoryName} --no-dependencies {extraArguments}",
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath);
|
||||
|
||||
logger.WriteLineInfo($"// dotnet restore took {restoreResult.ExecutionTime.TotalSeconds:0.##}s");
|
||||
needsIsolatedFolderForRestore
|
||||
? $"restore --packages {generateResult.ArtifactsPaths.PackagesDirectoryName} {extraArguments}"
|
||||
: $"restore {extraArguments}",
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath,
|
||||
logger);
|
||||
|
||||
if (!restoreResult.IsSuccess)
|
||||
return BuildResult.Failure(generateResult, new Exception(restoreResult.ProblemDescription));
|
||||
return restoreResult;
|
||||
|
||||
var buildResult = DotNetCliCommandExecutor.ExecuteCommand(
|
||||
CustomDotNetCliPath,
|
||||
$"build -c {buildPartition.BuildConfiguration} --no-restore --no-dependencies {extraArguments}",
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath);
|
||||
|
||||
logger.WriteLineInfo($"// dotnet build took {buildResult.ExecutionTime.TotalSeconds:0.##}s");
|
||||
$"build -c {buildPartition.BuildConfiguration} --no-restore {extraArguments}",
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath,
|
||||
logger);
|
||||
|
||||
if (!buildResult.IsSuccess)
|
||||
return BuildResult.Failure(generateResult, new Exception(buildResult.ProblemDescription));
|
||||
return buildResult;
|
||||
|
||||
var publishResult = DotNetCliCommandExecutor.ExecuteCommand(
|
||||
return DotNetCliCommandExecutor.ExecuteCommand(
|
||||
CustomDotNetCliPath,
|
||||
$"publish -c {buildPartition.BuildConfiguration} --no-restore --no-dependencies {extraArguments}",
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath);
|
||||
|
||||
logger.WriteLineInfo($"// dotnet publish took {publishResult.ExecutionTime.TotalSeconds:0.##}s");
|
||||
|
||||
if (!publishResult.IsSuccess &&
|
||||
!File.Exists(generateResult.ArtifactsPaths.ExecutablePath)) // dotnet cli could have succesfully builded the program, but returned 1 as exit code because it had some warnings
|
||||
{
|
||||
return BuildResult.Failure(generateResult, new Exception(publishResult.ProblemDescription));
|
||||
}
|
||||
|
||||
if (FilesToCopy != null)
|
||||
{
|
||||
var destinationFolder = Path.GetDirectoryName(generateResult.ArtifactsPaths.ExecutablePath);
|
||||
foreach (var fileToCopy in FilesToCopy)
|
||||
{
|
||||
File.Copy(fileToCopy, Path.Combine(destinationFolder, Path.GetFileName(fileToCopy)), overwrite: true);
|
||||
}
|
||||
}
|
||||
|
||||
return BuildResult.Success(generateResult);
|
||||
$"publish -c {buildPartition.BuildConfiguration} --no-restore {extraArguments}",
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath,
|
||||
logger);
|
||||
}
|
||||
|
||||
private static BuildResult CheckResult(GenerateResult generateResult, DotNetCliCommandExecutor.CommandResult commandResult)
|
||||
=> commandResult.IsSuccess || File.Exists(generateResult.ArtifactsPaths.ExecutablePath) // dotnet cli could have succesfully builded the program, but returned 1 as exit code because it had some warnings
|
||||
? BuildResult.Success(generateResult)
|
||||
: BuildResult.Failure(generateResult, new Exception(commandResult.ProblemDescription));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,18 +35,13 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli
|
|||
var restoreResult = DotNetCliCommandExecutor.ExecuteCommand(
|
||||
CustomDotNetCliPath,
|
||||
$"{RestoreCommand} {extraArguments}",
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath);
|
||||
|
||||
logger.WriteLineInfo($"// dotnet restore took {restoreResult.ExecutionTime.TotalSeconds:0.##}s");
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath,
|
||||
logger);
|
||||
|
||||
if (!restoreResult.IsSuccess)
|
||||
{
|
||||
return BuildResult.Failure(generateResult, new Exception(restoreResult.ProblemDescription));
|
||||
}
|
||||
|
||||
var buildResult = Build(generateResult, buildPartition.BuildConfiguration, extraArguments);
|
||||
|
||||
logger.WriteLineInfo($"// dotnet build took {buildResult.ExecutionTime.TotalSeconds:0.##}s");
|
||||
var buildResult = Build(generateResult, buildPartition.BuildConfiguration, extraArguments, logger);
|
||||
|
||||
if (!buildResult.IsSuccess)
|
||||
{
|
||||
|
@ -63,12 +58,13 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli
|
|||
return BuildResult.Success(generateResult);
|
||||
}
|
||||
|
||||
private DotNetCliCommandExecutor.CommandResult Build(GenerateResult generateResult, string configuration, string extraArguments)
|
||||
private DotNetCliCommandExecutor.CommandResult Build(GenerateResult generateResult, string configuration, string extraArguments, ILogger logger)
|
||||
{
|
||||
var withoutDependencies = DotNetCliCommandExecutor.ExecuteCommand(
|
||||
CustomDotNetCliPath,
|
||||
$"{GetBuildCommand(TargetFrameworkMoniker, true, configuration)} {extraArguments}",
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath);
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath,
|
||||
logger);
|
||||
|
||||
// at first we try to build the project without it's dependencies to save a LOT of time
|
||||
// in 99% of the cases it will work (the host process is running so it must be compiled!)
|
||||
|
@ -80,7 +76,8 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli
|
|||
return DotNetCliCommandExecutor.ExecuteCommand(
|
||||
CustomDotNetCliPath,
|
||||
$"{GetBuildCommand(TargetFrameworkMoniker, false, configuration)} {extraArguments}",
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath);
|
||||
generateResult.ArtifactsPaths.BuildArtifactsDirectoryPath,
|
||||
logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.ComponentModel;
|
|||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using BenchmarkDotNet.Loggers;
|
||||
|
||||
namespace BenchmarkDotNet.Toolchains.DotNetCli
|
||||
{
|
||||
|
@ -43,8 +44,10 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli
|
|||
}
|
||||
|
||||
internal static CommandResult ExecuteCommand(
|
||||
string customDotNetCliPath, string commandWithArguments, string workingDirectory)
|
||||
string customDotNetCliPath, string commandWithArguments, string workingDirectory, ILogger logger, bool useSharedCompilation = false)
|
||||
{
|
||||
commandWithArguments = $"{commandWithArguments} /p:UseSharedCompilation={useSharedCompilation.ToString().ToLowerInvariant()}";
|
||||
|
||||
using (var process = new Process { StartInfo = BuildStartInfo(customDotNetCliPath, workingDirectory, commandWithArguments) })
|
||||
{
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
|
@ -56,6 +59,8 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli
|
|||
process.WaitForExit();
|
||||
stopwatch.Stop();
|
||||
|
||||
logger.WriteLineInfo($"// {commandWithArguments} took {stopwatch.Elapsed.TotalSeconds:0.##}s and exited with {process.ExitCode}");
|
||||
|
||||
return process.ExitCode <= 0
|
||||
? CommandResult.Success(stopwatch.Elapsed, standardOutput)
|
||||
: CommandResult.Failure(stopwatch.Elapsed, standardError, standardOutput);
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using BenchmarkDotNet.Characteristics;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Engines;
|
||||
using BenchmarkDotNet.Extensions;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using BenchmarkDotNet.Loggers;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<Import Project="..\..\build\common.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyTitle>BenchmarkDotNet.IntegrationTests.ConfigPerAssembly</AssemblyTitle>
|
||||
<TargetFrameworks>net46;netcoreapp2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net46;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AssemblyName>BenchmarkDotNet.IntegrationTests.ConfigPerAssembly</AssemblyName>
|
||||
<PackageId>BenchmarkDotNet.IntegrationTests.ConfigPerAssembly</PackageId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<Import Project="..\..\build\common.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyTitle>BenchmarkDotNet.IntegrationTests.DisabledOptimizations</AssemblyTitle>
|
||||
<TargetFrameworks>net46;netcoreapp2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net46;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AssemblyName>BenchmarkDotNet.IntegrationTests.DisabledOptimizations</AssemblyName>
|
||||
<PackageId>BenchmarkDotNet.IntegrationTests.DisabledOptimizations</PackageId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<Import Project="..\..\build\common.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyTitle>BenchmarkDotNet.IntegrationTests.EnabledOptimizations</AssemblyTitle>
|
||||
<TargetFrameworks>net46;netcoreapp2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net46;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AssemblyName>BenchmarkDotNet.IntegrationTests.EnabledOptimizations</AssemblyName>
|
||||
<PackageId>BenchmarkDotNet.IntegrationTests.EnabledOptimizations</PackageId>
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\build\common.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyTitle>BenchmarkDotNet.IntegrationTests.ManualRunning</AssemblyTitle>
|
||||
<TargetFrameworks>net46;netcoreapp2.1</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AssemblyName>BenchmarkDotNet.IntegrationTests.ManualRunning</AssemblyName>
|
||||
<PackageId>BenchmarkDotNet.IntegrationTests.ManualRunning</PackageId>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<GenerateDocumentationFile>false</GenerateDocumentationFile>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="xunit.runner.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BenchmarkDotNet.IntegrationTests\BenchmarkDotNet.IntegrationTests.csproj" />
|
||||
<ProjectReference Include="..\BenchmarkDotNet.Tests\BenchmarkDotNet.Tests.csproj" />
|
||||
<ProjectReference Include="..\..\src\BenchmarkDotNet\BenchmarkDotNet.csproj" />
|
||||
<ProjectReference Include="..\..\src\BenchmarkDotNet.Diagnostics.Windows\BenchmarkDotNet.Diagnostics.Windows.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.4.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="System.Memory" Version="4.4.0-preview1-25305-02" />
|
||||
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,109 @@
|
|||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using BenchmarkDotNet.Toolchains.CustomCoreClr;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
// ReSharper disable InconsistentNaming we use crazy names for the types to include the version numbers
|
||||
|
||||
namespace BenchmarkDotNet.IntegrationTests.ManualRunning
|
||||
{
|
||||
/// <summary>
|
||||
/// to run these tests please clone and build CoreClr and CoreFx first,
|
||||
/// then update the hardcoded paths and versions
|
||||
/// and run following command from console:
|
||||
/// dotnet test -c Release -f netcoreapp2.1 --filter "FullyQualifiedName~BenchmarkDotNet.IntegrationTests.ManualRunning.LocalCoreClrToolchainTests"
|
||||
///
|
||||
/// in perfect world we would do this OOB for you, but building CoreCLR and CoreFX takes a LOT of time
|
||||
/// so it's not part of our CI jobs
|
||||
/// </summary>
|
||||
public class LocalCoreClrToolchainTests : BenchmarkTestExecutor
|
||||
{
|
||||
private const string CoreFxBinPackagesPath = @"C:\Projects\corefx\bin\packages\Debug"; // "/git/corefx/bin/packages/Release/";
|
||||
private const string CoreClrBinPackagesPath = @"C:\Projects\coreclr\bin\Product\Windows_NT.x64.Debug\.nuget\pkg"; // "/git/coreclr/bin/Product/Linux.x64.Release/.nuget/pkg/";
|
||||
private const string CoreClrPackagesPath = @"C:\Projects\coreclr\packages"; // "/git/coreclr/packages/";
|
||||
|
||||
private const string PrivateCoreFxNetCoreAppVersion = "4.5.0-preview3-26427-0";
|
||||
private const string ExpectedLocalCoreFxVersion = "4.6.26427.0";
|
||||
|
||||
private const string CoreClrVersion = "2.1.0-preview3-26420-0";
|
||||
private const string ExpectedLocalCoreClrVersion = "4.6.26420.0";
|
||||
|
||||
public LocalCoreClrToolchainTests(ITestOutputHelper output) : base(output) { }
|
||||
|
||||
[Fact]
|
||||
public void CanBenchmarkFullDotNetCoreStack()
|
||||
{
|
||||
var config = ManualConfig.CreateEmpty()
|
||||
.With(Job.Dry.With(
|
||||
CustomCoreClrToolchain.CreateBuilder()
|
||||
.UseCoreFxLocalBuild(PrivateCoreFxNetCoreAppVersion, CoreFxBinPackagesPath)
|
||||
.UseCoreClrLocalBuild(CoreClrVersion, CoreClrBinPackagesPath, CoreClrPackagesPath)
|
||||
.UseNuGetClearTag(false) // it should be removed after we add BDN to the dotnet/coreclr/dependencies.props file so all packages can be restored from CoreClrPackagesPath
|
||||
.ToToolchain()));
|
||||
|
||||
CanExecute<CheckLocalCoreClrAndCoreFxVersions>(config);
|
||||
}
|
||||
|
||||
public class CheckLocalCoreClrAndCoreFxVersions : CheckCoreClrAndCoreFxVersions
|
||||
{
|
||||
public CheckLocalCoreClrAndCoreFxVersions() : base(expectedCoreClrVersion: ExpectedLocalCoreClrVersion, expectedCoreFxVersion: ExpectedLocalCoreFxVersion) { }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanBenchmarkLocalCoreClrAndMyGetCoreFx()
|
||||
{
|
||||
var config = ManualConfig.CreateEmpty()
|
||||
.With(Job.Dry.With(
|
||||
CustomCoreClrToolchain.CreateBuilder()
|
||||
.UseCoreFxNuGet("4.5.0-preview3-26403-04")
|
||||
.UseCoreClrLocalBuild(CoreClrVersion, CoreClrBinPackagesPath, CoreClrPackagesPath)
|
||||
.UseNuGetClearTag(false)
|
||||
.ToToolchain()));
|
||||
|
||||
CanExecute<CheckLocalCoreClrAnd_4_6_26403_04_CoreFxVersions>(config);
|
||||
}
|
||||
|
||||
public class CheckLocalCoreClrAnd_4_6_26403_04_CoreFxVersions : CheckCoreClrAndCoreFxVersions
|
||||
{
|
||||
public CheckLocalCoreClrAnd_4_6_26403_04_CoreFxVersions() : base(expectedCoreClrVersion: ExpectedLocalCoreClrVersion, expectedCoreFxVersion: "4.6.26403.04") { }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanBenchmarkLocalCoreClrWithDefaultCoreFx()
|
||||
{
|
||||
var config = ManualConfig.CreateEmpty()
|
||||
.With(Job.Dry.With(
|
||||
CustomCoreClrToolchain.CreateBuilder()
|
||||
.UseCoreFxDefault()
|
||||
.UseCoreClrLocalBuild(CoreClrVersion, CoreClrBinPackagesPath, CoreClrPackagesPath)
|
||||
.UseNuGetClearTag(false)
|
||||
.ToToolchain()));
|
||||
|
||||
CanExecute<CheckLocalCoreClrVersion>(config);
|
||||
}
|
||||
|
||||
public class CheckLocalCoreClrVersion : CheckCoreClrAndCoreFxVersions
|
||||
{
|
||||
public CheckLocalCoreClrVersion() : base(expectedCoreClrVersion: ExpectedLocalCoreClrVersion) { }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanBenchmarkLocalCoreFxWithDefaultCoreClr()
|
||||
{
|
||||
var config = ManualConfig.CreateEmpty()
|
||||
.With(Job.Dry.With(
|
||||
CustomCoreClrToolchain.CreateBuilder()
|
||||
.UseCoreFxLocalBuild(PrivateCoreFxNetCoreAppVersion, CoreFxBinPackagesPath)
|
||||
.UseCoreClrDefault()
|
||||
.UseNuGetClearTag(false)
|
||||
.ToToolchain()));
|
||||
|
||||
CanExecute<CheckLocalCoreFxVersion>(config);
|
||||
}
|
||||
|
||||
public class CheckLocalCoreFxVersion : CheckCoreClrAndCoreFxVersions
|
||||
{
|
||||
public CheckLocalCoreFxVersion() : base(expectedCoreFxVersion: ExpectedLocalCoreFxVersion) { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"shadowCopy": false,
|
||||
"methodDisplay": "method"
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
#if !NETCOREAPP1_1
|
||||
using System;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Xunit;
|
||||
|
@ -27,5 +26,4 @@ namespace BenchmarkDotNet.IntegrationTests
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
<Import Project="..\..\build\common.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyTitle>BenchmarkDotNet.IntegrationTests</AssemblyTitle>
|
||||
<TargetFrameworks>net46;netcoreapp2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net46;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AssemblyName>BenchmarkDotNet.IntegrationTests</AssemblyName>
|
||||
<PackageId>BenchmarkDotNet.IntegrationTests</PackageId>
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace BenchmarkDotNet.IntegrationTests
|
|||
/// <param name="config">Optional custom config to be used instead of the default</param>
|
||||
/// <param name="fullValidation">Optional: disable validation (default = true/enabled)</param>
|
||||
/// <returns>The summary from the benchmark run</returns>
|
||||
internal Reports.Summary CanExecute<TBenchmark>(IConfig config = null, bool fullValidation = true)
|
||||
public Reports.Summary CanExecute<TBenchmark>(IConfig config = null, bool fullValidation = true)
|
||||
{
|
||||
return CanExecute(typeof(TBenchmark), config, fullValidation);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
|
||||
namespace BenchmarkDotNet.IntegrationTests
|
||||
{
|
||||
public abstract class CheckCoreClrAndCoreFxVersions
|
||||
{
|
||||
private string ExpectedCoreClrVersion { get; }
|
||||
|
||||
private string ExpectedCoreFxVersion { get; }
|
||||
|
||||
protected CheckCoreClrAndCoreFxVersions(string expectedCoreClrVersion = null, string expectedCoreFxVersion = null)
|
||||
{
|
||||
ExpectedCoreClrVersion = expectedCoreClrVersion;
|
||||
ExpectedCoreFxVersion = expectedCoreFxVersion;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void Check()
|
||||
{
|
||||
var coreFxAssemblyInfo = FileVersionInfo.GetVersionInfo(typeof(Regex).GetTypeInfo().Assembly.Location);
|
||||
var coreClrAssemblyInfo = FileVersionInfo.GetVersionInfo(typeof(object).GetTypeInfo().Assembly.Location);
|
||||
|
||||
Console.WriteLine($"// CoreFx version: {coreFxAssemblyInfo.FileVersion}, location {typeof(Regex).GetTypeInfo().Assembly.Location}, product version {coreFxAssemblyInfo.ProductVersion}");
|
||||
Console.WriteLine($"// CoreClr version {coreClrAssemblyInfo.FileVersion}, location {typeof(object).GetTypeInfo().Assembly.Location}, product version {coreClrAssemblyInfo.ProductVersion}");
|
||||
|
||||
if (ExpectedCoreFxVersion != null && coreFxAssemblyInfo.FileVersion != ExpectedCoreFxVersion)
|
||||
throw new Exception($"Wrong CoreFx version: was {coreFxAssemblyInfo.FileVersion}, should be {ExpectedCoreFxVersion}");
|
||||
|
||||
if (ExpectedCoreClrVersion != null && coreClrAssemblyInfo.FileVersion != ExpectedCoreClrVersion)
|
||||
throw new Exception($"Wrong CoreClr version: was {coreClrAssemblyInfo.FileVersion}, should be {ExpectedCoreClrVersion}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.IntegrationTests.Xunit;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using BenchmarkDotNet.Toolchains.CustomCoreClr;
|
||||
using Xunit.Abstractions;
|
||||
// ReSharper disable InconsistentNaming we use crazy names for the types to include the version numbers
|
||||
|
||||
namespace BenchmarkDotNet.IntegrationTests
|
||||
{
|
||||
public class CustomCoreClrToolchainTests : BenchmarkTestExecutor
|
||||
{
|
||||
private const string WeRunTheseTestsForNetCoreOnlyBecauseTheyTakeALotOfTime =
|
||||
"We run it only for .NET Core, it takes too long to run it for all frameworks";
|
||||
|
||||
public CustomCoreClrToolchainTests(ITestOutputHelper output) : base(output) { }
|
||||
|
||||
[FactDotNetCoreOnly(skipReason: WeRunTheseTestsForNetCoreOnlyBecauseTheyTakeALotOfTime)]
|
||||
public void CanBenchmarkGivenCoreFxMyGetBuild()
|
||||
{
|
||||
var config = ManualConfig.CreateEmpty()
|
||||
.With(Job.Dry.With(
|
||||
CustomCoreClrToolchain.CreateBuilder()
|
||||
.UseCoreClrDefault()
|
||||
.UseCoreFxNuGet("4.5.0-preview3-26328-01")
|
||||
.ToToolchain()));
|
||||
|
||||
CanExecute<Check_4_6_26328_01_CoreFxVersion>(config);
|
||||
}
|
||||
|
||||
public class Check_4_6_26328_01_CoreFxVersion : CheckCoreClrAndCoreFxVersions
|
||||
{
|
||||
public Check_4_6_26328_01_CoreFxVersion() : base(expectedCoreFxVersion: "4.6.26328.01") { }
|
||||
}
|
||||
|
||||
[FactDotNetCoreOnly(skipReason: WeRunTheseTestsForNetCoreOnlyBecauseTheyTakeALotOfTime)]
|
||||
public void CanBenchmarkGivenCoreClrMyGetBuild()
|
||||
{
|
||||
var config = ManualConfig.CreateEmpty()
|
||||
.With(Job.Dry.With(
|
||||
CustomCoreClrToolchain.CreateBuilder()
|
||||
.UseCoreFxDefault()
|
||||
.UseCoreClrNuGet("2.1.0-preview3-26329-08")
|
||||
.ToToolchain()));
|
||||
|
||||
CanExecute<Check_4_6_26329_08_CoreClrVersion>(config);
|
||||
}
|
||||
|
||||
public class Check_4_6_26329_08_CoreClrVersion : CheckCoreClrAndCoreFxVersions
|
||||
{
|
||||
public Check_4_6_26329_08_CoreClrVersion() : base(expectedCoreClrVersion: "4.6.26329.08") { }
|
||||
}
|
||||
|
||||
[FactDotNetCoreOnly(skipReason: WeRunTheseTestsForNetCoreOnlyBecauseTheyTakeALotOfTime)]
|
||||
public void CanBenchmarkGivenCoreClrAndCoreFxMyGetBuilds()
|
||||
{
|
||||
var config = ManualConfig.CreateEmpty()
|
||||
.With(Job.Dry.With(
|
||||
CustomCoreClrToolchain.CreateBuilder()
|
||||
.UseCoreFxNuGet("4.5.0-preview3-26330-06")
|
||||
.UseCoreClrNuGet("2.1.0-preview3-26329-08")
|
||||
.ToToolchain()));
|
||||
|
||||
CanExecute<Check_4_6_26329_08_CoreClrAnd_4_6_26330_06_CoreFxVersions>(config);
|
||||
}
|
||||
|
||||
public class Check_4_6_26329_08_CoreClrAnd_4_6_26330_06_CoreFxVersions : CheckCoreClrAndCoreFxVersions
|
||||
{
|
||||
public Check_4_6_26329_08_CoreClrAnd_4_6_26330_06_CoreFxVersions() : base(expectedCoreClrVersion: "4.6.26329.08", expectedCoreFxVersion: "4.6.26330.06") { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using Xunit;
|
||||
|
@ -16,9 +15,7 @@ namespace BenchmarkDotNet.IntegrationTests
|
|||
{
|
||||
}
|
||||
|
||||
#if !NETCOREAPP1_1 // ProcessStartInfo.EnvironmentVariables is avaialable for .NET Core 2.0+
|
||||
[Fact]
|
||||
#endif
|
||||
public void UserCanSpecifyEnvironmentVariables()
|
||||
{
|
||||
var variables = new [] { new EnvironmentVariable(Key, Value) };
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#if !NETCOREAPP1_1
|
||||
using System.Threading;
|
||||
using System.Threading;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.IntegrationTests.Xunit;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace BenchmarkDotNet.IntegrationTests
|
||||
|
@ -29,4 +27,3 @@ namespace BenchmarkDotNet.IntegrationTests
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
using BenchmarkDotNet.Portability;
|
||||
using Xunit;
|
||||
|
||||
namespace BenchmarkDotNet.IntegrationTests.Xunit
|
||||
{
|
||||
public class FactDotNetCoreOnlyAttribute : FactAttribute
|
||||
{
|
||||
public FactDotNetCoreOnlyAttribute(string skipReason)
|
||||
{
|
||||
// ReSharper disable once VirtualMemberCallInConstructor
|
||||
if (!RuntimeInformation.IsNetCore)
|
||||
Skip = skipReason;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
<Import Project="..\..\build\common.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyTitle>BenchmarkDotNet.Tests</AssemblyTitle>
|
||||
<TargetFrameworks>net46;netcoreapp2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net46;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
|
||||
<AssemblyName>BenchmarkDotNet.Tests</AssemblyName>
|
||||
<PackageId>BenchmarkDotNet.Tests</PackageId>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#if CLASSIC || NETCOREAPP2_0
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
|
@ -112,4 +111,3 @@ namespace BenchmarkDotNet.Tests.Exporters
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#if CLASSIC || NETCOREAPP2_0
|
||||
using System;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
@ -249,4 +248,3 @@ namespace BenchmarkDotNet.Tests.Exporters
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#if CLASSIC || NETCOREAPP2_0
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using ApprovalTests;
|
||||
using ApprovalTests.Namers;
|
||||
|
@ -32,4 +31,3 @@ namespace BenchmarkDotNet.Tests.Portability.Cpu
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,9 +1,5 @@
|
|||
using System.Runtime.InteropServices;
|
||||
#if CLASSIC || NETCOREAPP2_0
|
||||
using ApprovalTests.Reporters;
|
||||
#endif
|
||||
|
||||
[assembly: Guid("16c47abf-43e0-4db4-8151-36ca7a4082ae")]
|
||||
#if CLASSIC || NETCOREAPP2_0
|
||||
[assembly: IgnoreLineEndings(true)]
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#if !NETCOREAPP1_1
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using BenchmarkDotNet.Configs;
|
||||
|
@ -49,4 +48,3 @@ namespace BenchmarkDotNet.Tests.Validators
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче