From 96028937d1eeae6227145eacddff69d9b0add35b Mon Sep 17 00:00:00 2001 From: Andrey Akinshin Date: Sun, 14 May 2023 11:09:28 +0200 Subject: [PATCH] Enabled category inheritance, fix #2306 --- .../Attributes/BenchmarkCategoryAttribute.cs | 2 +- .../Running/BenchmarkConverter.cs | 6 +- .../Configs/CategoriesTests.cs | 55 +++++++++++++++++++ 3 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 tests/BenchmarkDotNet.Tests/Configs/CategoriesTests.cs diff --git a/src/BenchmarkDotNet.Annotations/Attributes/BenchmarkCategoryAttribute.cs b/src/BenchmarkDotNet.Annotations/Attributes/BenchmarkCategoryAttribute.cs index 50935d7132..f386d6cae4 100644 --- a/src/BenchmarkDotNet.Annotations/Attributes/BenchmarkCategoryAttribute.cs +++ b/src/BenchmarkDotNet.Annotations/Attributes/BenchmarkCategoryAttribute.cs @@ -3,7 +3,7 @@ namespace BenchmarkDotNet.Attributes { - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)] public class BenchmarkCategoryAttribute : Attribute { public string[] Categories { get; } diff --git a/src/BenchmarkDotNet/Running/BenchmarkConverter.cs b/src/BenchmarkDotNet/Running/BenchmarkConverter.cs index 1179daae02..ed546e37c6 100644 --- a/src/BenchmarkDotNet/Running/BenchmarkConverter.cs +++ b/src/BenchmarkDotNet/Running/BenchmarkConverter.cs @@ -248,11 +248,11 @@ private static IEnumerable GetArgumentsDefinitions(MethodInf private static string[] GetCategories(MethodInfo method) { var attributes = new List(); - attributes.AddRange(method.GetCustomAttributes(typeof(BenchmarkCategoryAttribute), false).OfType()); - var type = method.DeclaringType; + attributes.AddRange(method.GetCustomAttributes(typeof(BenchmarkCategoryAttribute), true).OfType()); + var type = method.ReflectedType; if (type != null) { - attributes.AddRange(type.GetTypeInfo().GetCustomAttributes(typeof(BenchmarkCategoryAttribute), false).OfType()); + attributes.AddRange(type.GetTypeInfo().GetCustomAttributes(typeof(BenchmarkCategoryAttribute), true).OfType()); attributes.AddRange(type.GetTypeInfo().Assembly.GetCustomAttributes().OfType()); } if (attributes.Count == 0) diff --git a/tests/BenchmarkDotNet.Tests/Configs/CategoriesTests.cs b/tests/BenchmarkDotNet.Tests/Configs/CategoriesTests.cs new file mode 100644 index 0000000000..b742c7af49 --- /dev/null +++ b/tests/BenchmarkDotNet.Tests/Configs/CategoriesTests.cs @@ -0,0 +1,55 @@ +using System.Linq; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; +using Xunit; +using Xunit.Abstractions; + +namespace BenchmarkDotNet.Tests.Configs +{ + public class CategoriesTests + { + private readonly ITestOutputHelper output; + + public CategoriesTests(ITestOutputHelper output) + { + this.output = output; + } + + [Fact] + public void CategoryInheritanceTest() + { + string Format(BenchmarkCase benchmarkCase) => + benchmarkCase.Descriptor.WorkloadMethod.Name + ": " + + string.Join("+", benchmarkCase.Descriptor.Categories.OrderBy(category => category)); + + var benchmarkCases = BenchmarkConverter + .TypeToBenchmarks(typeof(DerivedClass)) + .BenchmarksCases + .OrderBy(x => x.Descriptor.WorkloadMethod.Name) + .ToList(); + Assert.Equal(2, benchmarkCases.Count); + + output.WriteLine(Format(benchmarkCases[0])); + output.WriteLine(Format(benchmarkCases[1])); + + Assert.Equal("BaseMethod: BaseClassCategory+BaseMethodCategory+DerivedClassCategory", Format(benchmarkCases[0])); + Assert.Equal("DerivedMethod: BaseClassCategory+DerivedClassCategory+DerivedMethodCategory", Format(benchmarkCases[1])); + } + + [BenchmarkCategory("BaseClassCategory")] + public class BaseClass + { + [Benchmark] + [BenchmarkCategory("BaseMethodCategory")] + public void BaseMethod() { } + } + + [BenchmarkCategory("DerivedClassCategory")] + public class DerivedClass : BaseClass + { + [Benchmark] + [BenchmarkCategory("DerivedMethodCategory")] + public void DerivedMethod() { } + } + } +} \ No newline at end of file