use of org.sonar.java.se.xproc.MethodBehavior in project sonar-java by SonarSource.
the class BehaviorCacheTest method method_behavior_cache_should_be_filled_and_cleanup.
@Test
public void method_behavior_cache_should_be_filled_and_cleanup() {
SymbolicExecutionVisitor sev = createSymbolicExecutionVisitor("src/test/resources/se/MethodBehavior.java");
assertThat(sev.behaviorCache.behaviors.entrySet()).hasSize(4);
assertThat(sev.behaviorCache.behaviors.values().stream().filter(mb -> mb != null).count()).isEqualTo(4);
// check order of method exploration : last is the topMethod as it requires the other to get its behavior.
// Then, as we explore fully a path before switching to another one (see the LIFO in EGW) : qix is handled before foo.
assertThat(sev.behaviorCache.behaviors.keySet().stream().collect(Collectors.toList())).containsSequence("MethodBehavior#topMethod(Z)Z", "MethodBehavior#bar(Z)Z", "MethodBehavior#foo(Z)Z", "MethodBehavior#independent()V");
// method which can be overriden should not have behaviors: 'abstractMethod', 'publicMethod', 'nativeMethod'
assertThat(sev.behaviorCache.behaviors.keySet().stream().filter(s -> s.equals("#nativeMethod") || s.contains("#abstractMethod") || s.contains("#publicMethod")).map(s -> sev.behaviorCache.behaviors.get(s))).isEmpty();
assertThat(sev.behaviorCache.behaviors.entrySet()).hasSize(4);
sev.behaviorCache.cleanup();
assertThat(sev.behaviorCache.behaviors.entrySet()).isEmpty();
}
use of org.sonar.java.se.xproc.MethodBehavior in project sonar-java by SonarSource.
the class BehaviorCacheTest method clear_stack_when_taking_exceptional_path_from_method_invocation.
@Test
public void clear_stack_when_taking_exceptional_path_from_method_invocation() throws Exception {
Pair<SymbolicExecutionVisitor, SemanticModel> sevAndSemantic = createSymbolicExecutionVisitorAndSemantic("src/test/files/se/CleanStackWhenRaisingException.java");
SymbolicExecutionVisitor sev = sevAndSemantic.a;
SemanticModel semanticModel = sevAndSemantic.b;
MethodBehavior behavior = getMethodBehavior(sev, "foo");
assertThat(behavior.yields()).hasSize(4);
behavior.happyPathYields().forEach(y -> assertThat(y.resultConstraint()).isNull());
assertThat(behavior.happyPathYields().count()).isEqualTo(1);
List<ExceptionalYield> exceptionalYields = behavior.exceptionalPathYields().collect(Collectors.toList());
assertThat(exceptionalYields).hasSize(3);
assertThat(exceptionalYields.stream().filter(y -> y.exceptionType(semanticModel).isUnknown())).hasSize(1);
}
use of org.sonar.java.se.xproc.MethodBehavior in project sonar-java by SonarSource.
the class BehaviorCacheTest method test_peek.
@Test
public void test_peek() throws Exception {
Set<String> testedPre = new HashSet<>();
Set<String> testedPost = new HashSet<>();
SECheck check = new SECheck() {
@Override
public ProgramState checkPreStatement(CheckerContext context, Tree syntaxNode) {
if (syntaxNode.is(Tree.Kind.METHOD_INVOCATION)) {
Symbol.MethodSymbol symbol = (Symbol.MethodSymbol) ((MethodInvocationTree) syntaxNode).symbol();
MethodBehavior peekMethodBehavior = ((CheckerDispatcher) context).peekMethodBehavior(symbol);
assertThat(peekMethodBehavior).isNull();
testedPre.add(symbol.name());
}
return context.getState();
}
@Override
public ProgramState checkPostStatement(CheckerContext context, Tree syntaxNode) {
if (syntaxNode.is(Tree.Kind.METHOD_INVOCATION)) {
Symbol.MethodSymbol symbol = (Symbol.MethodSymbol) ((MethodInvocationTree) syntaxNode).symbol();
String methodName = symbol.name();
MethodBehavior peekMethodBehavior = ((CheckerDispatcher) context).peekMethodBehavior(symbol);
assertThat(peekMethodBehavior).isNotNull();
if ("foo".equals(methodName) || "isBlank".equals(methodName)) {
// foo should have been computed
assertThat(peekMethodBehavior.isComplete()).isTrue();
} else if ("bar".equals(methodName)) {
assertThat(peekMethodBehavior.isComplete()).isFalse();
}
testedPost.add(methodName);
}
return super.checkPostStatement(context, syntaxNode);
}
};
SymbolicExecutionVisitor sev = createSymbolicExecutionVisitor("src/test/files/se/BehaviorCachePeek.java", check);
assertThat(sev.behaviorCache.peek("org.apache.commons.lang.StringUtils#isBlank(Ljava/lang/String;)Z").isComplete()).isTrue();
assertThat(sev.behaviorCache.peek("org.foo.A#foo()Z").isComplete()).isTrue();
assertThat(sev.behaviorCache.peek("org.foo.A#bar()Z").isComplete()).isFalse();
assertThat(sev.behaviorCache.peek("org.foo.A#unknownMethod()Z")).isNull();
assertThat(sev.behaviorCache.behaviors.keySet()).containsOnly("org.foo.A#foo()Z");
assertThat(testedPre).containsOnly("foo", "bar", "isBlank");
assertThat(testedPost).containsOnly("foo", "bar", "isBlank");
}
use of org.sonar.java.se.xproc.MethodBehavior in project sonar-java by SonarSource.
the class BehaviorCacheTest method interrupted_exploration_does_not_create_method_yields.
@Test
public void interrupted_exploration_does_not_create_method_yields() throws Exception {
SymbolicExecutionVisitor sev = createSymbolicExecutionVisitor("src/test/files/se/PartialMethodYieldMaxStep.java");
assertThat(sev.behaviorCache.behaviors.entrySet()).hasSize(2);
MethodBehavior plopMethod = getMethodBehavior(sev, "foo");
assertThat(plopMethod.isComplete()).isFalse();
assertThat(plopMethod.yields()).isEmpty();
MethodBehavior barMethod = getMethodBehavior(sev, "bar");
assertThat(barMethod.isComplete()).isTrue();
assertThat(barMethod.yields()).hasSize(2);
}
use of org.sonar.java.se.xproc.MethodBehavior in project sonar-java by SonarSource.
the class ExplodedGraphWalkerTest method test_enqueueing_of_catch_blocks.
@Test
public void test_enqueueing_of_catch_blocks() {
SymbolicExecutionVisitor sev = createSymbolicExecutionVisitor("src/test/java/org/sonar/java/bytecode/se/testdata/ExceptionEnqueue.java");
MethodBehavior mb = sev.behaviorCache.behaviors.get("org.sonar.java.bytecode.se.testdata.ExceptionEnqueue#testCatchBlockEnqueue(Lorg/sonar/java/bytecode/se/testdata/ExceptionEnqueue;)Z");
List<HappyPathYield> happyPathYields = mb.happyPathYields().collect(Collectors.toList());
assertThat(happyPathYields).hasSize(1);
assertThat(happyPathYields.get(0).resultConstraint()).isNull();
mb = sev.behaviorCache.behaviors.get("org.sonar.java.bytecode.se.testdata.ExceptionEnqueue#testCatchBlockEnqueue2()Z");
happyPathYields = mb.happyPathYields().collect(Collectors.toList());
assertThat(happyPathYields).hasSize(1);
// correctly result constraint should be TRUE, but we enqueue also unreachable catch block which creates yield with FALSE result
// and yields are reduced consequently
assertThat(happyPathYields.get(0).resultConstraint()).isNull();
}
Aggregations