88using BenchmarkDotNet . IntegrationTests . Diagnosers ;
99using BenchmarkDotNet . Jobs ;
1010using BenchmarkDotNet . Tests . Loggers ;
11+ using BenchmarkDotNet . Toolchains ;
1112using BenchmarkDotNet . Toolchains . InProcess . Emit ;
13+ using BenchmarkDotNet . Toolchains . InProcess . NoEmit ;
1214using Xunit ;
1315using Xunit . Abstractions ;
16+ using RunMode = BenchmarkDotNet . Diagnosers . RunMode ;
1417
1518namespace BenchmarkDotNet . IntegrationTests ;
1619
1720public class MultipleInProcessDiagnosersTests : BenchmarkTestExecutor
1821{
1922 public MultipleInProcessDiagnosersTests ( ITestOutputHelper output ) : base ( output ) { }
2023
21- public static IEnumerable < object [ ] > GetDiagnoserCombinations ( )
24+ private static readonly RunMode [ ] AllRunModes = { RunMode . NoOverhead , RunMode . ExtraRun , RunMode . None } ;
25+
26+ private static IEnumerable < BaseMockInProcessDiagnoser [ ] > GetDiagnoserCombinations ( int count )
2227 {
23- // Two diagnosers with NoOverhead
24- yield return new object [ ]
28+ if ( count == 1 )
2529 {
26- new BaseMockInProcessDiagnoser [ ] { new MockInProcessDiagnoserNoOverhead ( ) , new MockInProcessDiagnoser ( ) } ,
27- typeof ( SimpleBenchmark ) ,
28- new [ ] { true , true }
29- } ;
30-
31- // Two diagnosers with ExtraRun and NoOverhead
32- yield return new object [ ]
30+ foreach ( var runMode in AllRunModes )
31+ {
32+ yield return [ CreateDiagnoser ( runMode , 0 ) ] ;
33+ }
34+ }
35+ else if ( count == 2 )
3336 {
34- new BaseMockInProcessDiagnoser [ ] { new MockInProcessDiagnoserExtraRun ( ) , new MockInProcessDiagnoserNoOverhead ( ) } ,
35- typeof ( SimpleBenchmark ) ,
36- new [ ] { true , true }
37- } ;
37+ foreach ( var runMode1 in AllRunModes )
38+ {
39+ foreach ( var runMode2 in AllRunModes )
40+ {
41+ yield return [ CreateDiagnoser ( runMode1 , 0 ) , CreateDiagnoser ( runMode2 , 1 ) ] ;
42+ }
43+ }
44+ }
45+ else if ( count == 3 )
46+ {
47+ foreach ( var runMode1 in AllRunModes )
48+ {
49+ foreach ( var runMode2 in AllRunModes )
50+ {
51+ foreach ( var runMode3 in AllRunModes )
52+ {
53+ yield return [ CreateDiagnoser ( runMode1 , 0 ) , CreateDiagnoser ( runMode2 , 1 ) , CreateDiagnoser ( runMode3 , 2 ) ] ;
54+ }
55+ }
56+ }
57+ }
58+ }
3859
39- // Three diagnosers with varying run modes (None should not collect results)
40- yield return new object [ ]
60+ private static BaseMockInProcessDiagnoser CreateDiagnoser ( RunMode runMode , int index )
61+ {
62+ return runMode switch
4163 {
42- new BaseMockInProcessDiagnoser [ ] { new MockInProcessDiagnoserNoOverhead ( ) , new MockInProcessDiagnoserExtraRun ( ) , new MockInProcessDiagnoserNone ( ) } ,
43- typeof ( SimpleBenchmark ) ,
44- new [ ] { true , true , false }
64+ RunMode . NoOverhead => index == 0 ? new MockInProcessDiagnoserNoOverhead ( ) : new MockInProcessDiagnoser ( ) ,
65+ RunMode . ExtraRun => new MockInProcessDiagnoserExtraRun ( ) ,
66+ RunMode . None => new MockInProcessDiagnoserNone ( ) ,
67+ _ => throw new ArgumentException ( $ "Unsupported run mode: { runMode } ")
4568 } ;
69+ }
4670
47- // Three different types
48- yield return new object [ ]
71+ public static IEnumerable < object [ ] > GetTestCombinations ( )
72+ {
73+ var toolchains = new IToolchain [ ]
4974 {
50- new BaseMockInProcessDiagnoser [ ] { new MockInProcessDiagnoserNoOverhead ( ) , new MockInProcessDiagnoser ( ) , new MockInProcessDiagnoserExtraRun ( ) } ,
51- typeof ( SimpleBenchmark ) ,
52- new [ ] { true , true , true }
75+ InProcessEmitToolchain . DontLogOutput ,
76+ new InProcessNoEmitToolchain ( TimeSpan . Zero , true ) ,
77+ null // Default toolchain
5378 } ;
5479
55- // Multiple benchmarks
56- yield return new object [ ]
80+ var counts = new [ ] { 1 , 2 , 3 } ;
81+
82+ foreach ( var toolchain in toolchains )
5783 {
58- new BaseMockInProcessDiagnoser [ ] { new MockInProcessDiagnoserNoOverhead ( ) , new MockInProcessDiagnoserExtraRun ( ) } ,
59- typeof ( MultipleBenchmarks ) ,
60- new [ ] { true , true }
61- } ;
84+ foreach ( var count in counts )
85+ {
86+ foreach ( var diagnosers in GetDiagnoserCombinations ( count ) )
87+ {
88+ yield return new object [ ] { diagnosers , toolchain } ;
89+ }
90+ }
91+ }
6292 }
6393
6494 [ Theory ]
65- [ MemberData ( nameof ( GetDiagnoserCombinations ) ) ]
66- public void MultipleInProcessDiagnosersWork ( BaseMockInProcessDiagnoser [ ] diagnosers , Type benchmarkType , bool [ ] shouldHaveResults )
95+ [ MemberData ( nameof ( GetTestCombinations ) ) ]
96+ public void MultipleInProcessDiagnosersWork ( BaseMockInProcessDiagnoser [ ] diagnosers , IToolchain toolchain )
6797 {
6898 var logger = new OutputLogger ( Output ) ;
69- var config = CreateInProcessConfig ( logger ) ;
99+ var config = CreateConfig ( logger , toolchain ) ;
70100
71101 foreach ( var diagnoser in diagnosers )
72102 {
73103 config = config . AddDiagnoser ( diagnoser ) ;
74104 }
75105
76- var summary = CanExecute ( benchmarkType , config ) ;
106+ var summary = CanExecute < SimpleBenchmark > ( config ) ;
77107
78- for ( int i = 0 ; i < diagnosers . Length ; i ++ )
108+ foreach ( var diagnoser in diagnosers )
79109 {
80- var diagnoser = diagnosers [ i ] ;
81- var shouldHaveResult = shouldHaveResults [ i ] ;
110+ bool shouldHaveResults = diagnoser . DiagnoserRunMode != RunMode . None ;
82111
83- if ( shouldHaveResult )
112+ if ( shouldHaveResults )
84113 {
85114 Assert . NotEmpty ( diagnoser . Results ) ;
86115 Assert . Equal ( summary . BenchmarksCases . Length , diagnoser . Results . Count ) ;
@@ -91,21 +120,18 @@ public void MultipleInProcessDiagnosersWork(BaseMockInProcessDiagnoser[] diagnos
91120 Assert . Empty ( diagnoser . Results ) ;
92121 }
93122 }
123+ }
94124
95- // For multiple benchmarks, verify all benchmark methods are present
96- if ( benchmarkType == typeof ( MultipleBenchmarks ) )
125+ private IConfig CreateConfig ( OutputLogger logger , IToolchain toolchain )
126+ {
127+ var job = Job . Dry ;
128+ if ( toolchain != null )
97129 {
98- var benchmarkMethods = summary . BenchmarksCases . Select ( bc => bc . Descriptor . WorkloadMethod . Name ) . ToList ( ) ;
99- Assert . Contains ( "Benchmark1" , benchmarkMethods ) ;
100- Assert . Contains ( "Benchmark2" , benchmarkMethods ) ;
101- Assert . Contains ( "Benchmark3" , benchmarkMethods ) ;
130+ job = job . WithToolchain ( toolchain ) ;
102131 }
103- }
104132
105- private IConfig CreateInProcessConfig ( OutputLogger logger )
106- {
107133 return new ManualConfig ( )
108- . AddJob ( Job . Dry . WithToolchain ( InProcessEmitToolchain . DontLogOutput ) )
134+ . AddJob ( job )
109135 . AddLogger ( logger )
110136 . AddColumnProvider ( DefaultColumnProviders . Instance ) ;
111137 }
0 commit comments