Skip to content

Commit 63c0ced

Browse files
authored
Notified users about private methods with Setup/Cleanup attributes (#1912)
* Notified users about private methods with Setup/Cleanup attributes * Added BenchmarkConverterTests.ThrowsWhenSetupAndCleanupMethodsAreNonPublic test Co-authored-by: epeshk <>
1 parent 569f4f5 commit 63c0ced

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

src/BenchmarkDotNet/Running/BenchmarkConverter.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ namespace BenchmarkDotNet.Running
1616
{
1717
public static partial class BenchmarkConverter
1818
{
19+
private const BindingFlags AllMethodsFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
20+
1921
public static BenchmarkRunInfo TypeToBenchmarks(Type type, IConfig config = null)
2022
{
2123
if (type.IsGenericTypeDefinition)
2224
throw new ArgumentException($"{type.Name} is generic type definition, use BenchmarkSwitcher for it"); // for "open generic types" should be used BenchmarkSwitcher
2325

2426
// We should check all methods including private to notify users about private methods with the [Benchmark] attribute
25-
var bindingFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
26-
var benchmarkMethods = GetOrderedBenchmarkMethods(type.GetMethods(bindingFlags));
27+
var benchmarkMethods = GetOrderedBenchmarkMethods(type.GetMethods(AllMethodsFlags));
2728

2829
return MethodsToBenchmarksWithFullConfig(type, benchmarkMethods, config);
2930
}
@@ -42,13 +43,13 @@ private static MethodInfo[] GetOrderedBenchmarkMethods(MethodInfo[] methods)
4243

4344
private static BenchmarkRunInfo MethodsToBenchmarksWithFullConfig(Type type, MethodInfo[] benchmarkMethods, IConfig config)
4445
{
45-
var allPublicMethods = type.GetMethods(); // benchmarkMethods can be filtered, without Setups, look #564
46+
var allMethods = type.GetMethods(AllMethodsFlags); // benchmarkMethods can be filtered, without Setups, look #564
4647
var configPerType = GetFullTypeConfig(type, config);
4748

48-
var globalSetupMethods = GetAttributedMethods<GlobalSetupAttribute>(allPublicMethods, "GlobalSetup");
49-
var globalCleanupMethods = GetAttributedMethods<GlobalCleanupAttribute>(allPublicMethods, "GlobalCleanup");
50-
var iterationSetupMethods = GetAttributedMethods<IterationSetupAttribute>(allPublicMethods, "IterationSetup");
51-
var iterationCleanupMethods = GetAttributedMethods<IterationCleanupAttribute>(allPublicMethods, "IterationCleanup");
49+
var globalSetupMethods = GetAttributedMethods<GlobalSetupAttribute>(allMethods, "GlobalSetup");
50+
var globalCleanupMethods = GetAttributedMethods<GlobalCleanupAttribute>(allMethods, "GlobalCleanup");
51+
var iterationSetupMethods = GetAttributedMethods<IterationSetupAttribute>(allMethods, "IterationSetup");
52+
var iterationCleanupMethods = GetAttributedMethods<IterationCleanupAttribute>(allMethods, "IterationCleanup");
5253

5354
var targets = GetTargets(benchmarkMethods, type, globalSetupMethods, globalCleanupMethods, iterationSetupMethods, iterationCleanupMethods).ToArray();
5455

@@ -135,8 +136,8 @@ private static Tuple<MethodInfo, TargetedAttribute>[] GetAttributedMethods<T>(Me
135136
return methods.SelectMany(m => m.GetCustomAttributes<T>()
136137
.Select(attr =>
137138
{
138-
AssertMethodHasCorrectSignature(methodName, m);
139139
AssertMethodIsAccessible(methodName, m);
140+
AssertMethodHasCorrectSignature(methodName, m);
140141
AssertMethodIsNotGeneric(methodName, m);
141142

142143
return new Tuple<MethodInfo, TargetedAttribute>(m, attr);

tests/BenchmarkDotNet.Tests/Running/BenchmarkConverterTests.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,5 +237,46 @@ public partial class BAC_Partial_DifferentFiles
237237
[Benchmark] public void A() { }
238238
[Benchmark] public void C() { }
239239
}
240+
241+
[Fact]
242+
public void ThrowsWhenSetupAndCleanupMethodsAreNonPublic()
243+
{
244+
var types = new[]
245+
{
246+
typeof(PrivateGlobalSetup),
247+
typeof(PrivateGlobalCleanup),
248+
typeof(PrivateIterationSetup),
249+
typeof(PrivateIterationCleanup)
250+
};
251+
252+
foreach (var type in types)
253+
{
254+
Assert.Throws<InvalidBenchmarkDeclarationException>(() => BenchmarkConverter.TypeToBenchmarks(type));
255+
}
256+
}
257+
258+
public class PrivateGlobalSetup
259+
{
260+
[GlobalSetup] private void X() { }
261+
[Benchmark] public void A() { }
262+
}
263+
264+
public class PrivateGlobalCleanup
265+
{
266+
[GlobalCleanup] private void X() { }
267+
[Benchmark] public void A() { }
268+
}
269+
270+
public class PrivateIterationSetup
271+
{
272+
[IterationSetup] private void X() { }
273+
[Benchmark] public void A() { }
274+
}
275+
276+
public class PrivateIterationCleanup
277+
{
278+
[IterationCleanup] private void X() { }
279+
[Benchmark] public void A() { }
280+
}
240281
}
241282
}

0 commit comments

Comments
 (0)