diff --git a/BenchmarkDotNet.sln b/BenchmarkDotNet.sln index 9537707749..ba31552c8a 100644 --- a/BenchmarkDotNet.sln +++ b/BenchmarkDotNet.sln @@ -47,7 +47,9 @@ 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("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkDotNet.Diagnostics.dotTrace", "src\BenchmarkDotNet.Diagnostics.dotTrace\BenchmarkDotNet.Diagnostics.dotTrace.csproj", "{C5BDA61F-3A56-4B59-901D-0A17E78F4076}" +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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -131,6 +133,10 @@ Global {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 + {AACA2C63-A85B-47AB-99FC-72C3FF408B14}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -155,6 +161,7 @@ Global {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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4D9AF12B-1F7F-45A7-9E8C-E4E46ADCBD1F} diff --git a/src/BenchmarkDotNet/Properties/AssemblyInfo.cs b/src/BenchmarkDotNet/Properties/AssemblyInfo.cs index 596c220645..5327197aa5 100644 --- a/src/BenchmarkDotNet/Properties/AssemblyInfo.cs +++ b/src/BenchmarkDotNet/Properties/AssemblyInfo.cs @@ -15,10 +15,12 @@ [assembly: InternalsVisibleTo("BenchmarkDotNet.Diagnostics.Windows,PublicKey=" + BenchmarkDotNetInfo.PublicKey)] [assembly: InternalsVisibleTo("BenchmarkDotNet.Diagnostics.dotTrace,PublicKey=" + BenchmarkDotNetInfo.PublicKey)] [assembly: InternalsVisibleTo("BenchmarkDotNet.IntegrationTests.ManualRunning,PublicKey=" + BenchmarkDotNetInfo.PublicKey)] +[assembly: InternalsVisibleTo("BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks,PublicKey=" + BenchmarkDotNetInfo.PublicKey)] #else [assembly: InternalsVisibleTo("BenchmarkDotNet.Tests")] [assembly: InternalsVisibleTo("BenchmarkDotNet.IntegrationTests")] [assembly: InternalsVisibleTo("BenchmarkDotNet.Diagnostics.Windows")] [assembly: InternalsVisibleTo("BenchmarkDotNet.Diagnostics.dotTrace")] [assembly: InternalsVisibleTo("BenchmarkDotNet.IntegrationTests.ManualRunning")] +[assembly: InternalsVisibleTo("BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks")] #endif \ No newline at end of file diff --git a/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs b/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs index cdb253447c..66f17ce246 100644 --- a/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs +++ b/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs @@ -1,6 +1,7 @@ using System; using BenchmarkDotNet.Environments; using BenchmarkDotNet.Extensions; +using BenchmarkDotNet.Helpers; using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Portability; using BenchmarkDotNet.Running; @@ -34,12 +35,19 @@ internal static IToolchain GetToolchain(this Runtime runtime, Descriptor descrip switch (runtime) { case ClrRuntime clrRuntime: - if (RuntimeInformation.IsNetCore || preferMsBuildToolchains) - return clrRuntime.RuntimeMoniker != RuntimeMoniker.NotRecognized - ? GetToolchain(clrRuntime.RuntimeMoniker) - : CsProjClassicNetToolchain.From(clrRuntime.MsBuildMoniker); - - return RoslynToolchain.Instance; + if (!preferMsBuildToolchains && RuntimeInformation.IsFullFramework && + // If dotnet SDK is not installed, we use RoslynToolchain. + (!HostEnvironmentInfo.GetCurrent().IsDotNetCliInstalled() + // Integration tests take too much time, because each benchmark run rebuilds the test suite and BenchmarkDotNet itself. + // To reduce the total duration of the CI workflows, we just use RoslynToolchain. + || XUnitHelper.IsIntegrationTest.Value)) + { + return RoslynToolchain.Instance; + } + + return clrRuntime.RuntimeMoniker != RuntimeMoniker.NotRecognized + ? GetToolchain(clrRuntime.RuntimeMoniker) + : CsProjClassicNetToolchain.From(clrRuntime.MsBuildMoniker); case MonoRuntime mono: if (RuntimeInformation.IsAndroid()) diff --git a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj new file mode 100644 index 0000000000..f5f83b5cda --- /dev/null +++ b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj @@ -0,0 +1,46 @@ + + + + BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks + + net461;net48;netcoreapp2.0;net7.0 + true + BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks + BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks + true + false + AnyCPU + true + true + + + + + + + + + + + + + + + + Always + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs new file mode 100644 index 0000000000..701b7d7ee1 --- /dev/null +++ b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs @@ -0,0 +1,50 @@ +using System; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Extensions; +using BenchmarkDotNet.Jobs; +using Xunit; + +namespace BenchmarkDotNet.IntegrationTests +{ + public class MultipleFrameworksTest : BenchmarkTestExecutor + { + private const string TfmEnvVarName = "TfmEnvVarName"; + + [Theory] + [InlineData(RuntimeMoniker.Net461)] + [InlineData(RuntimeMoniker.Net48)] + [InlineData(RuntimeMoniker.NetCoreApp20)] + [InlineData(RuntimeMoniker.Net70)] + public void EachFrameworkIsRebuilt(RuntimeMoniker runtime) + { + var config = ManualConfig.CreateEmpty().AddJob(Job.Dry.WithRuntime(runtime.GetRuntime()).WithEnvironmentVariable(TfmEnvVarName, runtime.ToString())); + CanExecute(config); + } + + public class ValuePerTfm + { + private const RuntimeMoniker moniker = +#if NET461 + RuntimeMoniker.Net461; +#elif NET48 + RuntimeMoniker.Net48; +#elif NETCOREAPP2_0 + RuntimeMoniker.NetCoreApp20; +#elif NET7_0 + RuntimeMoniker.Net70; +#else + RuntimeMoniker.NotRecognized; +#endif + + [Benchmark] + public void ThrowWhenWrong() + { + if (Environment.GetEnvironmentVariable(TfmEnvVarName) != moniker.ToString()) + { + throw new InvalidOperationException($"Has not been recompiled, the value was {Environment.GetEnvironmentVariable(TfmEnvVarName)}"); + } + } + } + } +} \ No newline at end of file diff --git a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning/BenchmarkDotNet.IntegrationTests.ManualRunning.csproj b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning/BenchmarkDotNet.IntegrationTests.ManualRunning.csproj index b0259a941e..020b73060c 100755 --- a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning/BenchmarkDotNet.IntegrationTests.ManualRunning.csproj +++ b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning/BenchmarkDotNet.IntegrationTests.ManualRunning.csproj @@ -16,6 +16,8 @@ + + @@ -25,7 +27,6 @@ -