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);
}
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)}");
}
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);
}
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);
}
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);
}
Aggregations