@@ -92,12 +92,31 @@ private static ImmutableConfig GetFullTypeConfig(Type type, IConfig? config)
9292 {
9393 config = config ?? DefaultConfig . Instance ;
9494
95- var typeAttributes = type . GetCustomAttributes ( true ) . OfType < IConfigSource > ( ) ;
9695 var assemblyAttributes = type . Assembly . GetCustomAttributes ( ) . OfType < IConfigSource > ( ) ;
97-
98- foreach ( var configFromAttribute in assemblyAttributes . Concat ( typeAttributes ) )
96+ foreach ( var configFromAttribute in assemblyAttributes )
9997 config = ManualConfig . Union ( config , configFromAttribute . Config ) ;
10098
99+ var typeAttributes = type . GetCustomAttributes ( true ) . OfType < IConfigSource > ( ) . ToArray ( ) ;
100+ if ( typeAttributes . Any ( x => x is UseLocalJobOnlyAttribute ) )
101+ {
102+ // UseLocalJobOnlyAttribute.can't be combined with other benchmark attribute that set non-default UnionRule.
103+ if ( typeAttributes . Any ( x => x . Config . UnionRule != ConfigUnionRule . Union ) )
104+ throw new InvalidBenchmarkDeclarationException ( $ "{ type . Name } using UseLocalJobOnlyAttribute, but other benchmarks attribute set another UnionRule.") ;
105+
106+ // Aggregate attribute-based configs.
107+ var typeConfig = ManualConfig . CreateEmpty ( ) ;
108+ foreach ( var configFromAttribute in typeAttributes )
109+ typeConfig = ManualConfig . Union ( typeConfig , configFromAttribute . Config ) ;
110+
111+ typeConfig . WithUnionRule ( ConfigUnionRule . UnionAndUseLocalJob ) ;
112+ config = ManualConfig . Union ( config , typeConfig ) ;
113+ }
114+ else
115+ {
116+ foreach ( var configFromAttribute in typeAttributes )
117+ config = ManualConfig . Union ( config , configFromAttribute . Config ) ;
118+ }
119+
101120 return ImmutableConfigBuilder . Create ( config ) ;
102121 }
103122
0 commit comments