diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index f42f2596a5..2856388209 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -27,7 +27,7 @@ jobs: run: ./build.cmd in-tests-core -e # Upload Artifacts with Unique Name - name: Upload test results - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: always() with: name: test-windows-core-trx-${{ github.run_id }} diff --git a/README.md b/README.md index 96feca8f9e..ed21385d53 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ The measured data can be exported to different formats (md, html, csv, xml, json ![](https://raw.githubusercontent.com/dotnet/BenchmarkDotNet/ec962b0bd6854c991d7a3ebd77037579165acb36/docs/images/v0.12.0/rplot.png) -*Supported runtimes:* .NET 5+, .NET Framework 4.6.1+, .NET Core 3.1+, Mono, NativeAOT +*Supported runtimes:* .NET 5+, .NET Framework 4.6.1+, .NET Core 2.0+, Mono, NativeAOT *Supported languages:* C#, F#, Visual Basic *Supported OS:* Windows, Linux, macOS *Supported architectures:* x86, x64, ARM, ARM64, Wasm and LoongArch64 @@ -135,8 +135,8 @@ If you want to compare benchmarks with each other, mark one of the benchmarks as the [baseline](https://benchmarkdotnet.org/articles/features/baselines.html) via `[Benchmark(Baseline = true)]`: BenchmarkDotNet will compare it with all of the other benchmarks. If you want to compare performance in different environments, use [jobs](https://benchmarkdotnet.org/articles/configs/jobs.html). -For example, you can run all the benchmarks on .NET Core 3.1 and Mono via - `[SimpleJob(RuntimeMoniker.NetCoreApp31)]` and `[SimpleJob(RuntimeMoniker.Mono)]`. +For example, you can run all the benchmarks on .NET 8.0 and Mono via + `[SimpleJob(RuntimeMoniker.Net80)]` and `[SimpleJob(RuntimeMoniker.Mono)]`. If you don't like attributes, you can call most of the APIs via the fluent style and write code like this: diff --git a/build/common.props b/build/common.props index ccae1753c3..972f3ea9f6 100644 --- a/build/common.props +++ b/build/common.props @@ -23,7 +23,7 @@ true annotations - + true diff --git a/docs/articles/faq.md b/docs/articles/faq.md index 8f1cd41dc3..1fcfb13b1a 100644 --- a/docs/articles/faq.md +++ b/docs/articles/faq.md @@ -13,9 +13,9 @@ See also: [BenchmarkDotNet#237](https://github.com/dotnet/BenchmarkDotNet/issues * **Q** Why can't I install BenchmarkDotNet in a new .NET Core Console App in Visual Studio 2017? - **A** BenchmarkDotNet supports only netcoreapp3.1+. + **A** BenchmarkDotNet supports only netcoreapp2.0+. Some old Visual Studio 2017 can create a new application which targets netcoreapp1.0. -You should upgrade it up to 3.1. +You should upgrade it up to 2.0. If you want to target netcoreapp1.0 in your main assembly, it's recommended to create a separated project for benchmarks. * **Q** I created a new .NET Core Console App in Visual Studio 2017. Now I want to run my code on CoreCLR, full .NET Framework, and Mono. How can I do it? @@ -23,7 +23,7 @@ If you want to target netcoreapp1.0 in your main assembly, it's recommended to c **A** Use the following lines in your `.csproj` file: ```xml - netcoreapp3.1;net46 + netcoreapp2.0;net46 AnyCPU ``` @@ -33,7 +33,7 @@ If you want to target netcoreapp1.0 in your main assembly, it's recommended to c [CoreJob, ClrJob, MonoJob] ``` -* **Q** My source code targets old versions of .NET Framework or .NET Core, but BenchmarkDotNet requires `net461` and `netcoreapp3.1`. How can I run benchmarks in this case? +* **Q** My source code targets old versions of .NET Framework or .NET Core, but BenchmarkDotNet requires `net461` and `netcoreapp2.0`. How can I run benchmarks in this case? **A** It's a good practice to introduce an additional console application (e.g. `MyAwesomeLibrary.Benchmarks`) which will depend on your code and BenchmarkDotNet. Due to the fact that users usually run benchmarks in a develop environment and don't distribute benchmarks for users, it shouldn't be a problem. diff --git a/docs/articles/guides/troubleshooting.md b/docs/articles/guides/troubleshooting.md index 2574f3d1aa..1a998886cc 100644 --- a/docs/articles/guides/troubleshooting.md +++ b/docs/articles/guides/troubleshooting.md @@ -11,7 +11,7 @@ How do you know that BenchmarkDotNet has failed to build the project? BDN is goi // ***** BenchmarkRunner: Start ***** // ***** Found 1 benchmark(s) in total ***** // ***** Building 1 exe(s) in Parallel: Start ***** -// start dotnet restore /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 /p:Deterministic=true /p:Optimize=true in C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4 +// start dotnet restore /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 /p:Deterministic=true /p:Optimize=true in C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\netcoreapp2.1\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4 // command took 0.51s and exited with 1 // ***** Done, took 00:00:00 (0.66 sec) ***** // Found 1 benchmarks: @@ -20,10 +20,10 @@ How do you know that BenchmarkDotNet has failed to build the project? BDN is goi // Build Error: Standard output: Standard error: - C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4\BenchmarkDotNet.Autogenerated.csproj(36,1): error MSB4025: The project file could not be loaded. Unexpected end of file while parsing Comment has occurred. Line 36, position 1. + C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\netcoreapp2.1\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4\BenchmarkDotNet.Autogenerated.csproj(36,1): error MSB4025: The project file could not be loaded. Unexpected end of file while parsing Comment has occurred. Line 36, position 1. // BenchmarkDotNet has failed to build the auto-generated boilerplate code. -// It can be found in C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4 +// It can be found in C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\netcoreapp2.1\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4 // Please follow the troubleshooting guide: https://benchmarkdotnet.org/articles/guides/troubleshooting.html ``` diff --git a/docs/articles/overview.md b/docs/articles/overview.md index f6f502d004..e777049ee1 100644 --- a/docs/articles/overview.md +++ b/docs/articles/overview.md @@ -10,7 +10,7 @@ name: Overview Create new console application and install the [BenchmarkDotNet](https://www.nuget.org/packages/BenchmarkDotNet/) NuGet package. We support: * *Projects:* classic and modern with PackageReferences -* *Runtimes:* Full .NET Framework (4.6+), .NET Core (3.1+), Mono, NativeAOT +* *Runtimes:* Full .NET Framework (4.6+), .NET Core (2.0+), Mono, NativeAOT * *OS:* Windows, Linux, MacOS * *Languages:* C#, F#, VB diff --git a/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs b/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs index 4ad24192e2..16b242d2dc 100644 --- a/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs +++ b/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs @@ -57,27 +57,22 @@ public enum RuntimeMoniker /// /// .NET Core 2.0 /// - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] - // Assigning explicit values so we can check for them without the compiler erroring. - NetCoreApp20 = 10, + NetCoreApp20, /// /// .NET Core 2.1 /// - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] - NetCoreApp21 = 11, + NetCoreApp21, /// /// .NET Core 2.2 /// - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] - NetCoreApp22 = 12, + NetCoreApp22, /// /// .NET Core 3.0 /// - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] - NetCoreApp30 = 13, + NetCoreApp30, /// /// .NET Core 3.1 diff --git a/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs b/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs index b7d23e9275..7616ca468c 100644 --- a/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs +++ b/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs @@ -112,6 +112,11 @@ internal override bool IsSupported(RuntimeMoniker runtimeMoniker) case RuntimeMoniker.NetCoreApp50: #pragma warning restore CS0618 // Type or member is obsolete return false; + case RuntimeMoniker.NetCoreApp20: + case RuntimeMoniker.NetCoreApp21: + case RuntimeMoniker.NetCoreApp22: + return OsDetector.IsWindows(); + case RuntimeMoniker.NetCoreApp30: case RuntimeMoniker.NetCoreApp31: return OsDetector.IsWindows() || OsDetector.IsLinux(); default: diff --git a/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs b/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs index 0dded47443..8b5d3a858f 100644 --- a/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs +++ b/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs @@ -115,6 +115,11 @@ internal override bool IsSupported(RuntimeMoniker runtimeMoniker) case RuntimeMoniker.NetCoreApp50: #pragma warning restore CS0618 // Type or member is obsolete return false; + case RuntimeMoniker.NetCoreApp20: + case RuntimeMoniker.NetCoreApp21: + case RuntimeMoniker.NetCoreApp22: + return OsDetector.IsWindows(); + case RuntimeMoniker.NetCoreApp30: case RuntimeMoniker.NetCoreApp31: return OsDetector.IsWindows() || OsDetector.IsLinux(); default: diff --git a/src/BenchmarkDotNet/BenchmarkDotNet.csproj b/src/BenchmarkDotNet/BenchmarkDotNet.csproj index 739ecbd85d..26938fb36a 100644 --- a/src/BenchmarkDotNet/BenchmarkDotNet.csproj +++ b/src/BenchmarkDotNet/BenchmarkDotNet.csproj @@ -23,7 +23,6 @@ - diff --git a/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs b/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs index b59836e395..51e1667c60 100644 --- a/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs +++ b/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs @@ -519,6 +519,10 @@ private static Job CreateJobForGivenRuntime(Job baseJob, string runtimeId, Comma .WithRuntime(runtimeMoniker.GetRuntime()) .WithToolchain(CsProjClassicNetToolchain.From(runtimeId, options.RestorePath?.FullName, options.CliPath?.FullName)); + case RuntimeMoniker.NetCoreApp20: + case RuntimeMoniker.NetCoreApp21: + case RuntimeMoniker.NetCoreApp22: + case RuntimeMoniker.NetCoreApp30: case RuntimeMoniker.NetCoreApp31: #pragma warning disable CS0618 // Type or member is obsolete case RuntimeMoniker.NetCoreApp50: diff --git a/src/BenchmarkDotNet/Diagnosers/EventPipeProfiler.cs b/src/BenchmarkDotNet/Diagnosers/EventPipeProfiler.cs index 81f1abdf75..c1c76e8c9e 100644 --- a/src/BenchmarkDotNet/Diagnosers/EventPipeProfiler.cs +++ b/src/BenchmarkDotNet/Diagnosers/EventPipeProfiler.cs @@ -62,9 +62,9 @@ public IEnumerable Validate(ValidationParameters validationPara { var runtime = benchmark.Job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, EnvironmentResolver.Instance); - if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp31) + if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp30) { - yield return new ValidationError(true, $"{nameof(EventPipeProfiler)} supports only .NET Core 3.1+", benchmark); + yield return new ValidationError(true, $"{nameof(EventPipeProfiler)} supports only .NET Core 3.0+", benchmark); } } } diff --git a/src/BenchmarkDotNet/Diagnosers/ThreadingDiagnoser.cs b/src/BenchmarkDotNet/Diagnosers/ThreadingDiagnoser.cs index 52059ca21c..36b2f942c3 100644 --- a/src/BenchmarkDotNet/Diagnosers/ThreadingDiagnoser.cs +++ b/src/BenchmarkDotNet/Diagnosers/ThreadingDiagnoser.cs @@ -45,9 +45,9 @@ public IEnumerable Validate(ValidationParameters validationPara { var runtime = benchmark.Job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, EnvironmentResolver.Instance); - if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp31) + if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp30) { - yield return new ValidationError(true, $"{nameof(ThreadingDiagnoser)} supports only .NET Core 3.1+", benchmark); + yield return new ValidationError(true, $"{nameof(ThreadingDiagnoser)} supports only .NET Core 3.0+", benchmark); } } } diff --git a/src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoser.cs b/src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoser.cs index 1c98b0752c..7d0f95326c 100644 --- a/src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoser.cs +++ b/src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoser.cs @@ -117,6 +117,11 @@ public IEnumerable Validate(ValidationParameters validationPara { var runtime = benchmark.Job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, EnvironmentResolver.Instance); + if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp30) + { + yield return new ValidationError(true, $"{nameof(DisassemblyDiagnoser)} supports only .NET Core 3.0+", benchmark); + } + if (ptrace_scope.Value == "2") { yield return new ValidationError(false, $"ptrace_scope is set to 2, {nameof(DisassemblyDiagnoser)} is going to work only if you run as sudo"); diff --git a/src/BenchmarkDotNet/Engines/GcStats.cs b/src/BenchmarkDotNet/Engines/GcStats.cs index 9c4c639737..ca60b0deea 100644 --- a/src/BenchmarkDotNet/Engines/GcStats.cs +++ b/src/BenchmarkDotNet/Engines/GcStats.cs @@ -39,7 +39,7 @@ private GcStats(int gen0Collections, int gen1Collections, int gen2Collections, l public long? GetBytesAllocatedPerOperation(BenchmarkCase benchmarkCase) { - bool excludeAllocationQuantumSideEffects = benchmarkCase.GetRuntime().RuntimeMoniker <= (RuntimeMoniker) 10; // the issue got fixed for .NET Core 2.0+ https://github.com/dotnet/coreclr/issues/10207 + bool excludeAllocationQuantumSideEffects = benchmarkCase.GetRuntime().RuntimeMoniker <= RuntimeMoniker.NetCoreApp20; // the issue got fixed for .NET Core 2.0+ https://github.com/dotnet/coreclr/issues/10207 long? allocatedBytes = GetTotalAllocatedBytes(excludeAllocationQuantumSideEffects); return allocatedBytes == null ? null diff --git a/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs b/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs index 66f918338c..53476adbc8 100644 --- a/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs +++ b/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs @@ -11,13 +11,9 @@ namespace BenchmarkDotNet.Environments { public class CoreRuntime : Runtime { - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] public static readonly CoreRuntime Core20 = new (RuntimeMoniker.NetCoreApp20, "netcoreapp2.0", ".NET Core 2.0"); - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] public static readonly CoreRuntime Core21 = new (RuntimeMoniker.NetCoreApp21, "netcoreapp2.1", ".NET Core 2.1"); - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] public static readonly CoreRuntime Core22 = new (RuntimeMoniker.NetCoreApp22, "netcoreapp2.2", ".NET Core 2.2"); - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] public static readonly CoreRuntime Core30 = new (RuntimeMoniker.NetCoreApp30, "netcoreapp3.0", ".NET Core 3.0"); public static readonly CoreRuntime Core31 = new (RuntimeMoniker.NetCoreApp31, "netcoreapp3.1", ".NET Core 3.1"); public static readonly CoreRuntime Core50 = new (RuntimeMoniker.Net50, "net5.0", ".NET 5.0"); @@ -69,6 +65,10 @@ internal static CoreRuntime FromVersion(Version version) { switch (version) { + case Version v when v.Major == 2 && v.Minor == 0: return Core20; + case Version v when v.Major == 2 && v.Minor == 1: return Core21; + case Version v when v.Major == 2 && v.Minor == 2: return Core22; + case Version v when v.Major == 3 && v.Minor == 0: return Core30; case Version v when v.Major == 3 && v.Minor == 1: return Core31; case Version v when v.Major == 5 && v.Minor == 0: return GetPlatformSpecific(Core50); case Version v when v.Major == 6 && v.Minor == 0: return GetPlatformSpecific(Core60); @@ -77,9 +77,7 @@ internal static CoreRuntime FromVersion(Version version) case Version v when v.Major == 9 && v.Minor == 0: return GetPlatformSpecific(Core90); case Version v when v.Major == 10 && v.Minor == 0: return GetPlatformSpecific(Core10_0); default: - return version >= new Version(3, 1) - ? CreateForNewVersion($"net{version.Major}.{version.Minor}", $".NET {version.Major}.{version.Minor}") - : throw new PlatformNotSupportedException($"netcoreapp{version.Major}.{version.Minor} is no longer supported. Use a newer runtime version or use BenchmarkDotNet v0.14.X or older."); + return CreateForNewVersion($"net{version.Major}.{version.Minor}", $".NET {version.Major}.{version.Minor}"); } } diff --git a/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs b/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs index ab905bd21e..94f82c8232 100644 --- a/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs +++ b/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs @@ -24,6 +24,14 @@ internal static Runtime GetRuntime(this RuntimeMoniker runtimeMoniker) return ClrRuntime.Net48; case RuntimeMoniker.Net481: return ClrRuntime.Net481; + case RuntimeMoniker.NetCoreApp20: + return CoreRuntime.Core20; + case RuntimeMoniker.NetCoreApp21: + return CoreRuntime.Core21; + case RuntimeMoniker.NetCoreApp22: + return CoreRuntime.Core22; + case RuntimeMoniker.NetCoreApp30: + return CoreRuntime.Core30; case RuntimeMoniker.NetCoreApp31: return CoreRuntime.Core31; case RuntimeMoniker.Net50: diff --git a/src/BenchmarkDotNet/Templates/CsProj.txt b/src/BenchmarkDotNet/Templates/CsProj.txt index 5cd08250dc..c20e376e3c 100644 --- a/src/BenchmarkDotNet/Templates/CsProj.txt +++ b/src/BenchmarkDotNet/Templates/CsProj.txt @@ -26,6 +26,8 @@ true false + + true BenchmarkDotNet.Autogenerated.UniqueProgramName diff --git a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt index 1db40072d1..7be0730fd7 100644 --- a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt +++ b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt @@ -20,6 +20,8 @@ true BenchmarkDotNet.Autogenerated.UniqueProgramName true + + true diff --git a/src/BenchmarkDotNet/Templates/WasmCsProj.txt b/src/BenchmarkDotNet/Templates/WasmCsProj.txt index e45f5c3789..fffc648e0b 100644 --- a/src/BenchmarkDotNet/Templates/WasmCsProj.txt +++ b/src/BenchmarkDotNet/Templates/WasmCsProj.txt @@ -26,6 +26,8 @@ false false false + + true BenchmarkDotNet.Autogenerated.UniqueProgramName diff --git a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs index 5e88641187..4aea1327f8 100644 --- a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs +++ b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs @@ -15,13 +15,9 @@ namespace BenchmarkDotNet.Toolchains.CsProj [PublicAPI] public class CsProjCoreToolchain : Toolchain, IEquatable { - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] [PublicAPI] public static readonly IToolchain NetCoreApp20 = From(NetCoreAppSettings.NetCoreApp20); - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] [PublicAPI] public static readonly IToolchain NetCoreApp21 = From(NetCoreAppSettings.NetCoreApp21); - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] [PublicAPI] public static readonly IToolchain NetCoreApp22 = From(NetCoreAppSettings.NetCoreApp22); - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] [PublicAPI] public static readonly IToolchain NetCoreApp30 = From(NetCoreAppSettings.NetCoreApp30); [PublicAPI] public static readonly IToolchain NetCoreApp31 = From(NetCoreAppSettings.NetCoreApp31); [PublicAPI] public static readonly IToolchain NetCoreApp50 = From(NetCoreAppSettings.NetCoreApp50); diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs index 7427b167d1..028e4f2bd3 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs @@ -1,6 +1,5 @@ using BenchmarkDotNet.Toolchains.MonoAotLLVM; using JetBrains.Annotations; -using System; namespace BenchmarkDotNet.Toolchains.DotNetCli { @@ -10,13 +9,9 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli [PublicAPI] public class NetCoreAppSettings { - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp20 = new ("netcoreapp2.0", null, ".NET Core 2.0"); - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp21 = new ("netcoreapp2.1", null, ".NET Core 2.1"); - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp22 = new ("netcoreapp2.2", null, ".NET Core 2.2"); - [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)] [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp30 = new ("netcoreapp3.0", null, ".NET Core 3.0"); [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp31 = new ("netcoreapp3.1", null, ".NET Core 3.1"); [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp50 = new ("net5.0", null, ".NET 5.0"); diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs index 061b64a9a8..f1e32d6c6b 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs @@ -143,6 +143,7 @@ private string GenerateProjectForNuGetBuild(BuildPartition buildPartition, Artif false false false + true {GetInstructionSetSettings(buildPartition)} {GetRuntimeSettings(buildPartition.RepresentativeBenchmarkCase.Job.Environment.Gc, buildPartition.Resolver)} diff --git a/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs b/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs index ba8b3c6863..2beab5018c 100644 --- a/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs +++ b/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs @@ -124,6 +124,18 @@ private static IToolchain GetToolchain(RuntimeMoniker runtimeMoniker) case RuntimeMoniker.Net481: return CsProjClassicNetToolchain.Net481; + case RuntimeMoniker.NetCoreApp20: + return CsProjCoreToolchain.NetCoreApp20; + + case RuntimeMoniker.NetCoreApp21: + return CsProjCoreToolchain.NetCoreApp21; + + case RuntimeMoniker.NetCoreApp22: + return CsProjCoreToolchain.NetCoreApp22; + + case RuntimeMoniker.NetCoreApp30: + return CsProjCoreToolchain.NetCoreApp30; + case RuntimeMoniker.NetCoreApp31: return CsProjCoreToolchain.NetCoreApp31; #pragma warning disable CS0618 // Type or member is obsolete diff --git a/src/BenchmarkDotNet/Validators/DotNetSdkVersionValidator.cs b/src/BenchmarkDotNet/Validators/DotNetSdkVersionValidator.cs index 14965a436d..17331b49f8 100644 --- a/src/BenchmarkDotNet/Validators/DotNetSdkVersionValidator.cs +++ b/src/BenchmarkDotNet/Validators/DotNetSdkVersionValidator.cs @@ -210,6 +210,10 @@ private static Version GetSdkVersionFromMoniker(RuntimeMoniker runtimeMoniker) RuntimeMoniker.Net472 => new Version(4, 7, 2), RuntimeMoniker.Net48 => new Version(4, 8), RuntimeMoniker.Net481 => new Version(4, 8, 1), + RuntimeMoniker.NetCoreApp20 => new Version(2, 0), + RuntimeMoniker.NetCoreApp21 => new Version(2, 1), + RuntimeMoniker.NetCoreApp22 => new Version(2, 2), + RuntimeMoniker.NetCoreApp30 => new Version(3, 0), RuntimeMoniker.NetCoreApp31 => new Version(3, 1), RuntimeMoniker.Net50 => new Version(5, 0), RuntimeMoniker.Net60 => new Version(6, 0), diff --git a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj index 282009baad..12457479b4 100644 --- a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj +++ b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj @@ -2,8 +2,8 @@ BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks - - net462;net48;netcoreapp3.1;net8.0 + + net461;net48;netcoreapp2.0;net8.0 $(NoWarn);NETSDK1138;NU1901;NU1902;NU1903;NU1904 false @@ -38,9 +38,10 @@ - - - + + + + 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 index a73a47e7c2..b9cf360c8f 100644 --- a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs +++ b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs @@ -3,7 +3,6 @@ using BenchmarkDotNet.Configs; using BenchmarkDotNet.Extensions; using BenchmarkDotNet.Jobs; -using BenchmarkDotNet.Portability; using Xunit; namespace BenchmarkDotNet.IntegrationTests.ManualRunning @@ -13,13 +12,13 @@ public class MultipleFrameworksTest : BenchmarkTestExecutor private const string TfmEnvVarName = "TfmEnvVarName"; [Theory] - [InlineData(RuntimeMoniker.Net462)] + [InlineData(RuntimeMoniker.Net461)] [InlineData(RuntimeMoniker.Net48)] - [InlineData(RuntimeMoniker.NetCoreApp31)] + [InlineData(RuntimeMoniker.NetCoreApp20)] [InlineData(RuntimeMoniker.Net80)] public void EachFrameworkIsRebuilt(RuntimeMoniker runtime) { -#if NET462 +#if NET461 // We cannot detect what target framework version the host was compiled for on full Framework, // which causes the RoslynToolchain to be used instead of CsProjClassicNetToolchain when the host is full Framework // (because full Framework always uses the version that's installed on the machine, unlike Core), @@ -40,12 +39,12 @@ public void EachFrameworkIsRebuilt(RuntimeMoniker runtime) public class ValuePerTfm { private const RuntimeMoniker moniker = -#if NET462 - RuntimeMoniker.Net462; +#if NET461 + RuntimeMoniker.Net461; #elif NET48 RuntimeMoniker.Net48; -#elif NETCOREAPP3_1 - RuntimeMoniker.NetCoreApp31; +#elif NETCOREAPP2_0 + RuntimeMoniker.NetCoreApp20; #elif NET8_0 RuntimeMoniker.Net80; #else @@ -57,7 +56,7 @@ public void ThrowWhenWrong() { if (Environment.GetEnvironmentVariable(TfmEnvVarName) != moniker.ToString()) { - throw new InvalidOperationException($"Has not been recompiled, the value was {Environment.GetEnvironmentVariable(TfmEnvVarName)}"); + throw new InvalidOperationException($"Has not been recompiled, the value was {moniker}, expected {Environment.GetEnvironmentVariable(TfmEnvVarName)}"); } } } diff --git a/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs b/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs index 2a4373eef0..a14ea685cb 100644 --- a/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs +++ b/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs @@ -271,10 +271,16 @@ public void IlCompilerPathParsedCorrectly() } [Theory] + [InlineData("netcoreapp2.0", true)] + [InlineData("netcoreapp2.1", true)] + [InlineData("netcoreapp2.2", true)] + [InlineData("netcoreapp3.0", true)] [InlineData("netcoreapp3.1", true)] [InlineData("net5.0", true)] [InlineData("net6.0", true)] + [InlineData("net7.0", true)] [InlineData("net8.0", true)] + [InlineData("net9.0", true)] [InlineData("net462", false)] [InlineData("net48", false)] public void DotNetCliParsedCorrectly(string tfm, bool isCore) @@ -421,15 +427,15 @@ public void PlatformSpecificMonikersAreSupported(string msBuildMoniker) [Fact] public void CanCompareFewDifferentRuntimes() { - var config = ConfigParser.Parse(["--runtimes", "net462", "MONO", "netcoreapp3.1", "nativeaot6.0", "nativeAOT7.0", "nativeAOT8.0"], + var config = ConfigParser.Parse(["--runtimes", "net462", "MONO", "netcoreapp2.0", "nativeaot6.0", "nativeAOT7.0", "nativeAOT8.0"], new OutputLogger(Output)).config; Assert.True(config.GetJobs().First().Meta.Baseline); // when the user provides multiple runtimes the first one should be marked as baseline Assert.Single(config.GetJobs(), job => job.Environment.Runtime is ClrRuntime clrRuntime && clrRuntime.MsBuildMoniker == "net462"); Assert.Single(config.GetJobs(), job => job.Environment.Runtime is MonoRuntime); Assert.Single(config.GetJobs(), job => - job.Environment.Runtime is CoreRuntime coreRuntime && coreRuntime.MsBuildMoniker == "netcoreapp3.1" && - coreRuntime.RuntimeMoniker == RuntimeMoniker.NetCoreApp31); + job.Environment.Runtime is CoreRuntime coreRuntime && coreRuntime.MsBuildMoniker == "netcoreapp2.0" && + coreRuntime.RuntimeMoniker == RuntimeMoniker.NetCoreApp20); Assert.Single(config.GetJobs(), job => job.Environment.Runtime is NativeAotRuntime nativeAot && nativeAot.MsBuildMoniker == "net6.0" && nativeAot.RuntimeMoniker == RuntimeMoniker.NativeAot60); diff --git a/tests/BenchmarkDotNet.Tests/RuntimeVersionDetectionTests.cs b/tests/BenchmarkDotNet.Tests/RuntimeVersionDetectionTests.cs index 876d0ae42e..f6286720fd 100644 --- a/tests/BenchmarkDotNet.Tests/RuntimeVersionDetectionTests.cs +++ b/tests/BenchmarkDotNet.Tests/RuntimeVersionDetectionTests.cs @@ -12,6 +12,10 @@ namespace BenchmarkDotNet.Tests public class RuntimeVersionDetectionTests { [Theory] + [InlineData(".NETCoreApp,Version=v2.0", RuntimeMoniker.NetCoreApp20, "netcoreapp2.0")] + [InlineData(".NETCoreApp,Version=v2.1", RuntimeMoniker.NetCoreApp21, "netcoreapp2.1")] + [InlineData(".NETCoreApp,Version=v2.2", RuntimeMoniker.NetCoreApp22, "netcoreapp2.2")] + [InlineData(".NETCoreApp,Version=v3.0", RuntimeMoniker.NetCoreApp30, "netcoreapp3.0")] [InlineData(".NETCoreApp,Version=v3.1", RuntimeMoniker.NetCoreApp31, "netcoreapp3.1")] [InlineData(".NETCoreApp,Version=v5.0", RuntimeMoniker.Net50, "net5.0")] [InlineData(".NETCoreApp,Version=v6.0", RuntimeMoniker.Net60, "net6.0")] @@ -40,6 +44,9 @@ public void TryGetVersionFromFrameworkNameHandlesInvalidInput(string? frameworkN } [Theory] + [InlineData(RuntimeMoniker.NetCoreApp21, "netcoreapp2.1", "Microsoft .NET Framework", "4.6.27817.01 @BuiltBy: dlab14-DDVSOWINAGE101 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/coreclr/tree/6f78fbb3f964b4f407a2efb713a186384a167e5c")] + [InlineData(RuntimeMoniker.NetCoreApp22, "netcoreapp2.2", "Microsoft .NET Framework", "4.6.27817.03 @BuiltBy: dlab14-DDVSOWINAGE101 @Branch: release/2.2 @SrcCode: https://github.com/dotnet/coreclr/tree/ce1d090d33b400a25620c0145046471495067cc7")] + [InlineData(RuntimeMoniker.NetCoreApp30, "netcoreapp3.0", "Microsoft .NET Core", "3.0.0-preview8-28379-12")] [InlineData(RuntimeMoniker.NetCoreApp31, "netcoreapp3.1", "Microsoft .NET Core", "3.1.0-something")] [InlineData(RuntimeMoniker.Net50, "net5.0", "Microsoft .NET Core", "5.0.0-alpha1.19415.3")] [InlineData(RuntimeMoniker.NotRecognized, "net123.0", "Microsoft .NET Core", "123.0.0-future")] @@ -67,6 +74,10 @@ public static IEnumerable FromNetCoreAppVersionHandlesValidInputArgume { string directoryPrefix = Path.GetTempPath(); // this test runs on Unix, it can not be hardcoded due to / \ difference + yield return new object[] { Path.Combine(directoryPrefix, "2.0.9") + Path.DirectorySeparatorChar, RuntimeMoniker.NetCoreApp20, "netcoreapp2.0" }; + yield return new object[] { Path.Combine(directoryPrefix, "2.1.12") + Path.DirectorySeparatorChar, RuntimeMoniker.NetCoreApp21, "netcoreapp2.1" }; + yield return new object[] { Path.Combine(directoryPrefix, "2.2.6") + Path.DirectorySeparatorChar, RuntimeMoniker.NetCoreApp22, "netcoreapp2.2" }; + yield return new object[] { Path.Combine(directoryPrefix, "3.0.0-preview8-28379-12") + Path.DirectorySeparatorChar, RuntimeMoniker.NetCoreApp30, "netcoreapp3.0" }; yield return new object[] { Path.Combine(directoryPrefix, "5.0.0-alpha1.19422.13") + Path.DirectorySeparatorChar, RuntimeMoniker.Net50, "net5.0" }; yield return new object[] { Path.Combine(directoryPrefix, "123.0.0") + Path.DirectorySeparatorChar, RuntimeMoniker.NotRecognized, "net123.0" }; } @@ -108,6 +119,12 @@ public void CurrentRuntimeIsProperlyRecognized() Assert.True(runtime is ClrRuntime); else Assert.True(runtime is MonoRuntime); +#elif NETCOREAPP2_1 + Assert.True(runtime is CoreRuntime coreRuntime && coreRuntime.RuntimeMoniker == RuntimeMoniker.NetCoreApp21); +#elif NETCOREAPP2_2 + Assert.True(runtime is CoreRuntime coreRuntime && coreRuntime.RuntimeMoniker == RuntimeMoniker.NetCoreApp22); +#elif NETCOREAPP3_0 + Assert.True(runtime is CoreRuntime coreRuntime && coreRuntime.RuntimeMoniker == RuntimeMoniker.NetCoreApp30); #elif NETCOREAPP3_1 Assert.True(runtime is CoreRuntime coreRuntime && coreRuntime.RuntimeMoniker == RuntimeMoniker.NetCoreApp31); #elif NETCOREAPP5_0 diff --git a/tests/BenchmarkDotNet.Tests/dotMemory/DotMemoryTests.cs b/tests/BenchmarkDotNet.Tests/dotMemory/DotMemoryTests.cs index 1ef074112c..d3aec8dd96 100644 --- a/tests/BenchmarkDotNet.Tests/dotMemory/DotMemoryTests.cs +++ b/tests/BenchmarkDotNet.Tests/dotMemory/DotMemoryTests.cs @@ -1,5 +1,4 @@ using System; -using System.Reflection; using BenchmarkDotNet.Diagnostics.dotMemory; using BenchmarkDotNet.Jobs; using Xunit; @@ -13,12 +12,6 @@ public void AllRuntimeMonikerAreKnown() { var diagnoser = new DotMemoryDiagnoser(); foreach (RuntimeMoniker moniker in Enum.GetValues(typeof(RuntimeMoniker))) - { - // Just check that it doesn't throw exceptions, ignoring deprecated values. - if (typeof(RuntimeMoniker).GetMember(moniker.ToString())[0].GetCustomAttribute() == null) - { - diagnoser.IsSupported(moniker); - } - } + diagnoser.IsSupported(moniker); // Just check that it doesn't throw exceptions } } \ No newline at end of file diff --git a/tests/BenchmarkDotNet.Tests/dotTrace/DotTraceTests.cs b/tests/BenchmarkDotNet.Tests/dotTrace/DotTraceTests.cs index f7788f874c..751412fd55 100644 --- a/tests/BenchmarkDotNet.Tests/dotTrace/DotTraceTests.cs +++ b/tests/BenchmarkDotNet.Tests/dotTrace/DotTraceTests.cs @@ -1,5 +1,4 @@ using System; -using System.Reflection; using BenchmarkDotNet.Diagnostics.dotTrace; using BenchmarkDotNet.Jobs; using Xunit; @@ -13,12 +12,6 @@ public void AllRuntimeMonikerAreKnown() { var diagnoser = new DotTraceDiagnoser(); foreach (RuntimeMoniker moniker in Enum.GetValues(typeof(RuntimeMoniker))) - { - // Just check that it doesn't throw exceptions, ignoring deprecated values. - if (typeof(RuntimeMoniker).GetMember(moniker.ToString())[0].GetCustomAttribute() == null) - { - diagnoser.IsSupported(moniker); - } - } + diagnoser.IsSupported(moniker); // Just check that it doesn't throw exceptions } } \ No newline at end of file