Skip to content

Commit

Permalink
Closes #130 - Add option to exclude lambdas from instrumentation
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusoe committed Mar 13, 2019
1 parent ed3dc89 commit 788bad6
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 18 deletions.
Expand Up @@ -24,4 +24,8 @@ public class AdvancedScopeSettings {
*/
private boolean disableSafetyMechanisms = false;

/**
* Defines whether lambda classes should be excluded from the declared scope.
*/
private boolean excludeLambdas = true;
}
Expand Up @@ -73,7 +73,11 @@ private InstrumentationScope resolveScope(InstrumentationScopeSettings scopeSett
}

//we ensure that we only match types which contain at least one matched method
typeMatcher = typeMatcher.and(declaresMethod(methodMatcher));
if (typeMatcher.equals(any())) {
typeMatcher = declaresMethod(methodMatcher);
} else {
typeMatcher = typeMatcher.and(declaresMethod(methodMatcher));
}

return new InstrumentationScope(typeMatcher, methodMatcher);
}
Expand All @@ -84,6 +88,10 @@ private InstrumentationScope resolveScope(InstrumentationScopeSettings scopeSett
private ElementMatcher.Junction<TypeDescription> buildTypeMatcher(InstrumentationScopeSettings scopeSettings) {
MatcherChainBuilder<TypeDescription> builder = new MatcherChainBuilder<>();

if (scopeSettings.getAdvanced() == null || scopeSettings.getAdvanced().isExcludeLambdas()) {
builder.and(not(nameContains("$$Lambda$")));
}

if (scopeSettings.getSuperclass() != null) {
processSuperclass(builder, scopeSettings.getSuperclass());
}
Expand Down
Expand Up @@ -113,7 +113,24 @@ public void ruleWithEmptyScope() {

Map<String, InstrumentationScope> result = scopeResolver.resolve(settings);

assertThat(result).flatExtracting(scopeKey).contains(new InstrumentationScope(any().and(declaresMethod(any())), any()));
ElementMatcher.Junction<TypeDescription> typeMatcher = not(nameContains("$$Lambda$")).and(declaresMethod(any()));

assertThat(result).flatExtracting(scopeKey).contains(new InstrumentationScope(typeMatcher, any()));
}

@Test
public void ruleWithScope_includingLambdas() {
String scopeKey = "scope-key";
setRuleSettings("rule-key", true, Collections.singletonMap("scope-key", true));
AdvancedScopeSettings advancedScopeSettings = new AdvancedScopeSettings();
advancedScopeSettings.setExcludeLambdas(false);
setScopeSettings(scopeKey, null, null, null, null, advancedScopeSettings);

Map<String, InstrumentationScope> result = scopeResolver.resolve(settings);

ElementMatcher.Junction<TypeDescription> typeMatcher = declaresMethod(any());

assertThat(result).flatExtracting(scopeKey).contains(new InstrumentationScope(typeMatcher, any()));
}

@Test
Expand All @@ -125,8 +142,10 @@ public void ruleWithScope_emptyTypeEmptyMethodEmptyAdvanced() {

Map<String, InstrumentationScope> result = scopeResolver.resolve(settings);

ElementMatcher.Junction<TypeDescription> typeMatcher = not(nameContains("$$Lambda$")).and(declaresMethod(any()));

assertThat(result).containsOnlyKeys(scopeKey);
assertThat(result).flatExtracting(scopeKey).contains(new InstrumentationScope(any().and(declaresMethod(any())), any()));
assertThat(result).flatExtracting(scopeKey).contains(new InstrumentationScope(typeMatcher, any()));
}

@Test
Expand All @@ -146,7 +165,7 @@ public void ruleWithScope_emptyMethodEmptyAdvanced() {
assertThat(result.get(scopeKey))
.extracting(InstrumentationScope::getTypeMatcher, InstrumentationScope::getMethodMatcher)
.containsExactly(
named("class.Class").and(IsAnnotatedMatcher.of(named("annotation"))).and(declaresMethod(any())),
not(nameContains("$$Lambda$")).and(named("class.Class").and(IsAnnotatedMatcher.of(named("annotation")))).and(declaresMethod(any())),
any());
}

Expand All @@ -166,7 +185,7 @@ public void ruleWithScope_emptyAdvanced() {
assertThat(result.get(scopeKey))
.extracting(InstrumentationScope::getTypeMatcher, InstrumentationScope::getMethodMatcher)
.containsExactly(
named("class.Class").and(declaresMethod(not(isConstructor()).and(named("method")))),
not(nameContains("$$Lambda$")).and(named("class.Class")).and(declaresMethod(not(isConstructor()).and(named("method")))),
not(isConstructor()).and(named("method")));
}

Expand All @@ -187,7 +206,7 @@ public void ruleWithScope() {
assertThat(result.get(scopeKey))
.extracting(InstrumentationScope::getTypeMatcher, InstrumentationScope::getMethodMatcher)
.containsExactly(
named("class.Class").and(declaresMethod(not(isConstructor()).and(named("method")))),
not(nameContains("$$Lambda$")).and(named("class.Class")).and(declaresMethod(not(isConstructor()).and(named("method")))),
not(isConstructor()).and(named("method")));
}

Expand All @@ -211,10 +230,12 @@ public void methodMatcherProperties_normalMethod() {
.and(nameMatches("method"))
.and(isSynchronized());

ElementMatcher.Junction<TypeDescription> typeMatcher = not(nameContains("$$Lambda$")).and(declaresMethod(methodMatcher));

assertThat(result).containsOnlyKeys(scopeKey);
assertThat(result.get(scopeKey))
.extracting(InstrumentationScope::getTypeMatcher, InstrumentationScope::getMethodMatcher)
.containsExactly(any().and(declaresMethod(methodMatcher)), methodMatcher);
.containsExactly(typeMatcher, methodMatcher);
}

@Test
Expand All @@ -236,10 +257,12 @@ public void methodMatcherProperties_constructor() {
.and(isPublic())
.and(takesArguments(1).and(takesArgument(0, named("any.Class"))));

ElementMatcher.Junction<TypeDescription> typeMatcher = not(nameContains("$$Lambda$")).and(declaresMethod(methodMatcher));

assertThat(result).containsOnlyKeys(scopeKey);
assertThat(result.get(scopeKey))
.extracting(InstrumentationScope::getTypeMatcher, InstrumentationScope::getMethodMatcher)
.containsExactly(any().and(declaresMethod(methodMatcher)), methodMatcher);
.containsExactly(typeMatcher, methodMatcher);
}

@Test
Expand All @@ -256,15 +279,14 @@ public void methodMatcherProperties_multipleMethods() {

ElementMatcher.Junction<MethodDescription> methodMatcher = not(isConstructor())
.and(named("methodA"))
.or(
not(isConstructor())
.and(named("methodB"))
);
.or(not(isConstructor()).and(named("methodB")));

ElementMatcher.Junction<TypeDescription> typeMatcher = not(nameContains("$$Lambda$")).and(declaresMethod(methodMatcher));

assertThat(result).containsOnlyKeys(scopeKey);
assertThat(result.get(scopeKey))
.extracting(InstrumentationScope::getTypeMatcher, InstrumentationScope::getMethodMatcher)
.containsExactly(any().and(declaresMethod(methodMatcher)), methodMatcher);
.containsExactly(typeMatcher, methodMatcher);
}

@Test
Expand All @@ -283,8 +305,6 @@ public void methodMatcherProperties_onlyInherited() {

Map<String, InstrumentationScope> result = scopeResolver.resolve(settings);

ElementMatcher.Junction<TypeDescription> typeMatcher = hasSuperType(not(isInterface()).and(named("any.Superclass")))
.and(hasSuperType(isInterface().and(named("any.Interface"))));

ElementMatcher.Junction<MethodDescription> methodMatcher = not(isConstructor())
.and(named("methodA"))
Expand All @@ -293,10 +313,15 @@ public void methodMatcherProperties_onlyInherited() {
.or(named("any.Superclass").and(not(isInterface())))
));

ElementMatcher.Junction<TypeDescription> typeMatcher = not(nameContains("$$Lambda$"))
.and(hasSuperType(not(isInterface()).and(named("any.Superclass"))))
.and(hasSuperType(isInterface().and(named("any.Interface"))))
.and(declaresMethod(methodMatcher));

assertThat(result).containsOnlyKeys(scopeKey);
assertThat(result.get(scopeKey))
.extracting(InstrumentationScope::getTypeMatcher, InstrumentationScope::getMethodMatcher)
.containsExactly(typeMatcher.and(declaresMethod(methodMatcher)), methodMatcher);
.containsExactly(typeMatcher, methodMatcher);
}

@Test
Expand All @@ -312,7 +337,7 @@ public void typeTargets_superclass() {

Map<String, InstrumentationScope> result = scopeResolver.resolve(settings);

ElementMatcher.Junction<TypeDescription> typeMatcher = hasSuperType(not(isInterface()).and(named("any.Superclass").and(IsAnnotatedMatcher.of(named("annotation")))));
ElementMatcher.Junction<TypeDescription> typeMatcher = not(nameContains("$$Lambda$")).and(hasSuperType(not(isInterface()).and(named("any.Superclass").and(IsAnnotatedMatcher.of(named("annotation"))))));

assertThat(result).containsOnlyKeys(scopeKey);
assertThat(result.get(scopeKey))
Expand All @@ -333,7 +358,7 @@ public void typeTargets_interfaces() {

Map<String, InstrumentationScope> result = scopeResolver.resolve(settings);

ElementMatcher.Junction<TypeDescription> typeMatcher = hasSuperType(isInterface().and(named("any.Interface").and(IsAnnotatedMatcher.of(named("annotation")))));
ElementMatcher.Junction<TypeDescription> typeMatcher = not(nameContains("$$Lambda$")).and(hasSuperType(isInterface().and(named("any.Interface").and(IsAnnotatedMatcher.of(named("annotation"))))));

assertThat(result).containsOnlyKeys(scopeKey);
assertThat(result.get(scopeKey))
Expand Down

0 comments on commit 788bad6

Please sign in to comment.