Search in sources :

Example 1 with MethodBehavior

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();
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) ArgumentMatchers.anySet(org.mockito.ArgumentMatchers.anySet) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) ArgumentMatchers.nullable(org.mockito.ArgumentMatchers.nullable) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) HashSet(java.util.HashSet) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) NullDereferenceCheck(org.sonar.java.se.checks.NullDereferenceCheck) SECheck(org.sonar.java.se.checks.SECheck) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) SETestUtils.createSymbolicExecutionVisitorAndSemantic(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitorAndSemantic) Set(java.util.Set) Test(org.junit.Test) Tree(org.sonar.plugins.java.api.tree.Tree) Collectors(java.util.stream.Collectors) JavaFileScannerContext(org.sonar.plugins.java.api.JavaFileScannerContext) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) Mockito.verify(org.mockito.Mockito.verify) List(java.util.List) Mockito.never(org.mockito.Mockito.never) Rule(org.junit.Rule) LogTester(org.sonar.api.utils.log.LogTester) SemanticModel(org.sonar.java.resolve.SemanticModel) ExceptionalYield(org.sonar.java.se.xproc.ExceptionalYield) Symbol(org.sonar.plugins.java.api.semantic.Symbol) LoggerLevel(org.sonar.api.utils.log.LoggerLevel) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Mockito.mock(org.mockito.Mockito.mock) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) Test(org.junit.Test)

Example 2 with MethodBehavior

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);
}
Also used : ExceptionalYield(org.sonar.java.se.xproc.ExceptionalYield) SemanticModel(org.sonar.java.resolve.SemanticModel) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) Test(org.junit.Test)

Example 3 with MethodBehavior

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");
}
Also used : SECheck(org.sonar.java.se.checks.SECheck) Symbol(org.sonar.plugins.java.api.semantic.Symbol) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) Tree(org.sonar.plugins.java.api.tree.Tree) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 4 with MethodBehavior

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);
}
Also used : SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) Test(org.junit.Test)

Example 5 with MethodBehavior

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();
}
Also used : HappyPathYield(org.sonar.java.se.xproc.HappyPathYield) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) Test(org.junit.Test)

Aggregations

MethodBehavior (org.sonar.java.se.xproc.MethodBehavior)36 Test (org.junit.Test)30 SemanticModel (org.sonar.java.resolve.SemanticModel)10 BehaviorCache (org.sonar.java.se.xproc.BehaviorCache)10 HappyPathYield (org.sonar.java.se.xproc.HappyPathYield)10 MethodYield (org.sonar.java.se.xproc.MethodYield)10 List (java.util.List)8 Collectors (java.util.stream.Collectors)8 SymbolicValue (org.sonar.java.se.symbolicvalues.SymbolicValue)8 Type (org.sonar.plugins.java.api.semantic.Type)8 Lists (com.google.common.collect.Lists)6 SquidClassLoader (org.sonar.java.bytecode.loader.SquidClassLoader)6 ProgramState (org.sonar.java.se.ProgramState)6 DivisionByZeroCheck (org.sonar.java.se.checks.DivisionByZeroCheck)6 BooleanConstraint (org.sonar.java.se.constraint.BooleanConstraint)6 ObjectConstraint (org.sonar.java.se.constraint.ObjectConstraint)6 ExceptionalYield (org.sonar.java.se.xproc.ExceptionalYield)6 File (java.io.File)5 Collection (java.util.Collection)5 Set (java.util.Set)5