Search in sources :

Example 6 with SymbolicExecutionVisitor

use of org.sonar.java.se.SymbolicExecutionVisitor in project sonar-java by SonarSource.

the class ExceptionalYieldTest method exceptional_yields.

@Test
public void exceptional_yields() {
    Pair<SymbolicExecutionVisitor, SemanticModel> sevAndSemantic = createSymbolicExecutionVisitorAndSemantic("src/test/files/se/ExceptionalYields.java");
    SymbolicExecutionVisitor sev = sevAndSemantic.a;
    SemanticModel semanticModel = sevAndSemantic.b;
    MethodBehavior mb = getMethodBehavior(sev, "myMethod");
    assertThat(mb.yields()).hasSize(4);
    List<ExceptionalYield> exceptionalYields = mb.exceptionalPathYields().collect(Collectors.toList());
    assertThat(exceptionalYields).hasSize(3);
    // runtime exception
    Optional<ExceptionalYield> runtimeException = exceptionalYields.stream().filter(y -> y.exceptionType(semanticModel).isUnknown()).findFirst();
    assertThat(runtimeException.isPresent()).isTrue();
    MethodYield runtimeExceptionYield = runtimeException.get();
    assertThat(runtimeExceptionYield.parametersConstraints.get(0).get(BooleanConstraint.class)).isEqualTo(BooleanConstraint.FALSE);
    // exception from other method call
    Optional<ExceptionalYield> implicitException = exceptionalYields.stream().filter(y -> y.exceptionType(semanticModel).is("org.foo.MyException2")).findFirst();
    assertThat(implicitException.isPresent()).isTrue();
    MethodYield implicitExceptionYield = implicitException.get();
    assertThat(implicitExceptionYield.parametersConstraints.get(0).get(BooleanConstraint.class)).isEqualTo(BooleanConstraint.FALSE);
    // explicitly thrown exception
    Optional<ExceptionalYield> explicitException = exceptionalYields.stream().filter(y -> y.exceptionType(semanticModel).is("org.foo.MyException1")).findFirst();
    assertThat(explicitException.isPresent()).isTrue();
    MethodYield explicitExceptionYield = explicitException.get();
    assertThat(explicitExceptionYield.parametersConstraints.get(0).get(BooleanConstraint.class)).isEqualTo(BooleanConstraint.TRUE);
}
Also used : JavaParser(org.sonar.java.ast.parser.JavaParser) SETestUtils.mockMethodBehavior(org.sonar.java.se.SETestUtils.mockMethodBehavior) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SquidClassLoader(org.sonar.java.bytecode.loader.SquidClassLoader) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) SETestUtils(org.sonar.java.se.SETestUtils) Set(java.util.Set) Test(org.junit.Test) CompilationUnitTree(org.sonar.plugins.java.api.tree.CompilationUnitTree) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) List(java.util.List) Pair(org.sonar.java.se.Pair) SemanticModel(org.sonar.java.resolve.SemanticModel) Optional(java.util.Optional) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) SETestUtils.createSymbolicExecutionVisitorAndSemantic(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitorAndSemantic) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) SemanticModel(org.sonar.java.resolve.SemanticModel) SETestUtils.mockMethodBehavior(org.sonar.java.se.SETestUtils.mockMethodBehavior) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) Test(org.junit.Test)

Example 7 with SymbolicExecutionVisitor

use of org.sonar.java.se.SymbolicExecutionVisitor in project sonar-java by SonarSource.

the class ExceptionalYieldTest method test_toString.

@Test
public void test_toString() throws Exception {
    SymbolicExecutionVisitor sev = createSymbolicExecutionVisitor("src/test/files/se/ExceptionalYields.java");
    Set<String> yieldsToString = getMethodBehavior(sev, "myMethod").exceptionalPathYields().map(MethodYield::toString).collect(Collectors.toSet());
    assertThat(yieldsToString).contains("{params: [[FALSE]], exceptional}", "{params: [[TRUE]], exceptional (org.foo.MyException1)}", "{params: [[FALSE]], exceptional (org.foo.MyException2)}");
}
Also used : SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) Test(org.junit.Test)

Example 8 with SymbolicExecutionVisitor

use of org.sonar.java.se.SymbolicExecutionVisitor in project sonar-java by SonarSource.

the class MethodBehaviorTest method method_behavior_handling_finally.

@Test
public void method_behavior_handling_finally() {
    Pair<SymbolicExecutionVisitor, SemanticModel> visitorAndSemantic = createSymbolicExecutionVisitorAndSemantic("src/test/resources/se/ReturnAndFinally.java");
    SymbolicExecutionVisitor sev = visitorAndSemantic.a;
    SemanticModel semanticModel = visitorAndSemantic.b;
    assertThat(sev.behaviorCache.behaviors.entrySet()).hasSize(5);
    MethodBehavior foo = getMethodBehavior(sev, "foo");
    assertThat(foo.yields()).hasSize(4);
    assertThat(foo.happyPathYields()).hasSize(2);
    assertThat(foo.exceptionalPathYields()).hasSize(2);
    MethodBehavior qix = getMethodBehavior(sev, "qix");
    List<MethodYield> qixYield = qix.yields();
    assertThat(qixYield.stream().filter(y -> y.parametersConstraints.get(0).get(ObjectConstraint.class) != ObjectConstraint.NULL).allMatch(y -> y instanceof ExceptionalYield)).isTrue();
    assertThat(qixYield.stream().filter(y -> y.parametersConstraints.get(0).get(ObjectConstraint.class) == ObjectConstraint.NULL && y instanceof ExceptionalYield).count()).isEqualTo(2);
    assertThat(qixYield.stream().filter(y -> y instanceof HappyPathYield).allMatch(y -> y.parametersConstraints.get(0).get(ObjectConstraint.class) == ObjectConstraint.NULL)).isTrue();
    MethodBehavior returnInFinally = getMethodBehavior(sev, "returnInFinally");
    assertThat(returnInFinally.yields()).hasSize(1);
    assertThat(returnInFinally.happyPathYields()).hasSize(1);
    MethodBehavior returningException = getMethodBehavior(sev, "returningException");
    assertThat(returningException.yields()).hasSize(3);
    assertThat(returningException.happyPathYields()).hasSize(2);
    assertThat(returningException.exceptionalPathYields()).hasSize(1);
    MethodBehavior rethrowingException = getMethodBehavior(sev, "rethrowingException");
    assertThat(rethrowingException.yields()).hasSize(4);
    assertThat(rethrowingException.happyPathYields()).hasSize(1);
    assertThat(rethrowingException.exceptionalPathYields()).hasSize(3);
    assertThat(rethrowingException.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).isUnknown())).hasSize(1);
    assertThat(rethrowingException.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).is("java.lang.Exception"))).hasSize(1);
    assertThat(rethrowingException.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).is("org.foo.MyException"))).hasSize(1);
}
Also used : ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Test(org.junit.Test) Collectors(java.util.stream.Collectors) ConstraintsByDomain(org.sonar.java.se.constraint.ConstraintsByDomain) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) List(java.util.List) Pair(org.sonar.java.se.Pair) SemanticModel(org.sonar.java.resolve.SemanticModel) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) SETestUtils.createSymbolicExecutionVisitorAndSemantic(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitorAndSemantic) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) Constraint(org.sonar.java.se.constraint.Constraint) Nullable(javax.annotation.Nullable) SemanticModel(org.sonar.java.resolve.SemanticModel) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) Test(org.junit.Test)

Example 9 with SymbolicExecutionVisitor

use of org.sonar.java.se.SymbolicExecutionVisitor in project sonar-java by SonarSource.

the class MethodBehaviorTest method method_behavior_yields.

@Test
public void method_behavior_yields() {
    SymbolicExecutionVisitor sev = createSymbolicExecutionVisitor("src/test/resources/se/MethodYields.java");
    MethodBehavior mb = getMethodBehavior(sev, "method");
    List<MethodYield> yields = mb.yields();
    assertThat(yields).hasSize(3);
    List<HappyPathYield> trueResults = mb.happyPathYields().filter(my -> BooleanConstraint.TRUE.equals(my.resultConstraint().get(BooleanConstraint.class))).collect(Collectors.toList());
    assertThat(trueResults).hasSize(1);
    HappyPathYield trueResult = trueResults.get(0);
    // 'a' has constraint "null"
    assertThat(((ObjectConstraint) trueResult.parametersConstraints.get(0).get(ObjectConstraint.class)).isNull()).isTrue();
    // no constraint on 'b'
    assertThat(((ObjectConstraint) trueResult.parametersConstraints.get(0).get(ObjectConstraint.class)).isNull()).isTrue();
    // result SV is a different SV than 'a' and 'b'
    assertThat(trueResult.resultIndex()).isEqualTo(-1);
    List<HappyPathYield> falseResults = mb.happyPathYields().filter(my -> BooleanConstraint.FALSE.equals(my.resultConstraint().get(BooleanConstraint.class))).collect(Collectors.toList());
    assertThat(falseResults).hasSize(2);
    // for both "False" results, 'a' has the constraint "not null"
    assertThat(falseResults.stream().filter(my -> !((ObjectConstraint) my.parametersConstraints.get(0).get(ObjectConstraint.class)).isNull()).count()).isEqualTo(2);
    // 1) 'b' has constraint "false", result is 'b'
    assertThat(falseResults.stream().filter(my -> BooleanConstraint.FALSE.equals(my.parametersConstraints.get(1).get(BooleanConstraint.class)) && my.resultIndex() == 1).count()).isEqualTo(1);
    // 2) 'b' is "true", result is a different SV than 'a' and 'b'
    assertThat(falseResults.stream().filter(my -> BooleanConstraint.TRUE.equals(my.parametersConstraints.get(1).get(BooleanConstraint.class)) && my.resultIndex() == -1).count()).isEqualTo(1);
}
Also used : ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Test(org.junit.Test) Collectors(java.util.stream.Collectors) ConstraintsByDomain(org.sonar.java.se.constraint.ConstraintsByDomain) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) List(java.util.List) Pair(org.sonar.java.se.Pair) SemanticModel(org.sonar.java.resolve.SemanticModel) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) SETestUtils.createSymbolicExecutionVisitorAndSemantic(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitorAndSemantic) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) Constraint(org.sonar.java.se.constraint.Constraint) Nullable(javax.annotation.Nullable) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) Test(org.junit.Test)

Example 10 with SymbolicExecutionVisitor

use of org.sonar.java.se.SymbolicExecutionVisitor in project sonar-java by SonarSource.

the class ExceptionalCheckBasedYieldTest method creation_of_new_yield.

@Test
public void creation_of_new_yield() {
    String methodName = "method";
    SymbolicExecutionVisitor sev;
    MethodBehavior mb;
    Pair<SymbolicExecutionVisitor, SemanticModel> visitorAndSemantic = createSymbolicExecutionVisitorAndSemantic(FILENAME);
    sev = visitorAndSemantic.a;
    SemanticModel semanticModel = visitorAndSemantic.b;
    mb = getMethodBehavior(sev, methodName);
    // no creation of custom yields, 3 method yields
    assertThat(mb.yields()).hasSize(3);
    assertThat(mb.happyPathYields()).hasSize(1);
    assertThat(mb.happyPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == null)).hasSize(1);
    assertThat(mb.happyPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.TRUE)).hasSize(0);
    assertThat(mb.happyPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.FALSE)).hasSize(0);
    assertThat(mb.exceptionalPathYields()).hasSize(2);
    assertThat(mb.exceptionalPathYields()).as("All the exceptional yields are runtime exceptions").allMatch(y -> y.exceptionType(semanticModel).isUnknown());
    assertThat(mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.TRUE)).hasSize(1);
    assertThat(mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.FALSE)).hasSize(1);
    // new rule discard any call to plantFlowers(true) by creating a new yield
    SECheck check = new TestSECheck();
    sev = createSymbolicExecutionVisitor(FILENAME, check);
    mb = getMethodBehavior(sev, methodName);
    assertThat(mb.yields()).hasSize(4);
    // 2nd param can never be null
    assertThat(mb.yields().stream().filter(y -> y.parametersConstraints.get(0).isEmpty() && y.parametersConstraints.get(1).get(ObjectConstraint.class) == ObjectConstraint.NULL)).hasSize(1);
    assertThat(mb.yields().stream().filter(y -> y.parametersConstraints.get(1).get(ObjectConstraint.class) != ObjectConstraint.NULL)).hasSize(3);
    // happyPath with first parameter being true is discarded
    assertThat(mb.happyPathYields()).hasSize(2);
    // still 2 exceptional path
    assertThat(mb.exceptionalPathYields()).hasSize(2);
    assertThat(mb.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).isUnknown())).hasSize(1);
    assertThat(mb.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).isClass())).hasSize(1);
    assertThat(mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.FALSE)).hasSize(1);
    ExceptionalYield exceptionalYield = mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.TRUE).findFirst().get();
    assertThat(exceptionalYield).isInstanceOf(ExceptionalCheckBasedYield.class);
    ExceptionalCheckBasedYield seCheckExceptionalYield = (ExceptionalCheckBasedYield) exceptionalYield;
    assertThat(seCheckExceptionalYield.check()).isEqualTo(TestSECheck.class);
    assertThat(seCheckExceptionalYield.exceptionType(semanticModel)).isNotNull();
    assertThat(seCheckExceptionalYield.exceptionType(semanticModel).is("java.lang.UnsupportedOperationException")).isTrue();
    assertThat(seCheckExceptionalYield.exceptionType(semanticModel).isSubtypeOf("java.lang.RuntimeException")).isTrue();
    assertThat(seCheckExceptionalYield.generatedByCheck(check)).isTrue();
    assertThat(seCheckExceptionalYield.generatedByCheck(new SECheck() {
    })).isFalse();
    assertThat(seCheckExceptionalYield.parameterCausingExceptionIndex()).isEqualTo(0);
}
Also used : SECheck(org.sonar.java.se.checks.SECheck) SemanticModel(org.sonar.java.resolve.SemanticModel) SETestUtils.mockMethodBehavior(org.sonar.java.se.SETestUtils.mockMethodBehavior) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) Test(org.junit.Test)

Aggregations

SymbolicExecutionVisitor (org.sonar.java.se.SymbolicExecutionVisitor)15 Test (org.junit.Test)13 SETestUtils.createSymbolicExecutionVisitor (org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor)13 SETestUtils.getMethodBehavior (org.sonar.java.se.SETestUtils.getMethodBehavior)11 SETestUtils.mockMethodBehavior (org.sonar.java.se.SETestUtils.mockMethodBehavior)8 SemanticModel (org.sonar.java.resolve.SemanticModel)6 ObjectConstraint (org.sonar.java.se.constraint.ObjectConstraint)6 List (java.util.List)5 BooleanConstraint (org.sonar.java.se.constraint.BooleanConstraint)5 ArrayList (java.util.ArrayList)4 Collectors (java.util.stream.Collectors)4 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)4 SquidClassLoader (org.sonar.java.bytecode.loader.SquidClassLoader)4 Pair (org.sonar.java.se.Pair)4 SETestUtils.createSymbolicExecutionVisitorAndSemantic (org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitorAndSemantic)4 CompilationUnitTree (org.sonar.plugins.java.api.tree.CompilationUnitTree)4 JavaFileScannerContext (org.sonar.plugins.java.api.JavaFileScannerContext)3 Optional (java.util.Optional)2 Set (java.util.Set)2 Nullable (javax.annotation.Nullable)2