|
38 | 38 | import java.util.ArrayList;
|
39 | 39 | import java.util.Collection;
|
40 | 40 | import java.util.Collections;
|
41 |
| -import java.util.Iterator; |
42 | 41 | import java.util.List;
|
43 | 42 |
|
44 | 43 | /**
|
|
47 | 46 | public final class ConstraintModelBuilder implements InstrumentedProgram<Boolean> {
|
48 | 47 |
|
49 | 48 | private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
50 |
| - private boolean viablePatch; |
51 | 49 | private final ClassLoader classLoader;
|
52 | 50 | private RuntimeValues<Boolean> runtimeValues;
|
53 | 51 | private SourceLocation sourceLocation;
|
@@ -86,7 +84,7 @@ public Collection<Specification<Boolean>> collectSpecifications(URL[] classpath,
|
86 | 84 | // come back to default mode
|
87 | 85 | AngelicExecution.disable();
|
88 | 86 |
|
89 |
| - if (!determineViability(firstResult, secondResult)) { |
| 87 | + if (!isSynthesisPossible(firstResult, secondResult)) { |
90 | 88 | return Collections.emptyList();
|
91 | 89 | }
|
92 | 90 | /* to collect information for passing tests */
|
@@ -140,26 +138,31 @@ public void testRunStarted(Description description)
|
140 | 138 |
|
141 | 139 |
|
142 | 140 |
|
143 |
| - private boolean determineViability(final Result firstResult, final Result secondResult) { |
144 |
| - Collection<Description> firstFailures = TestSuiteExecution.collectDescription(firstResult.getFailures()); |
145 |
| - Collection<Description> secondFailures = TestSuiteExecution.collectDescription(secondResult.getFailures()); |
146 |
| - firstFailures.retainAll(secondFailures); |
147 |
| - viablePatch = firstFailures.isEmpty(); |
148 |
| - int nbFirstSuccess = firstResult.getRunCount() - firstResult.getFailureCount(); |
149 |
| - int nbSecondSuccess = secondResult.getRunCount() - secondResult.getFailureCount(); |
150 |
| - if (!viablePatch || (nbFirstSuccess == 0 && nbSecondSuccess == 0)) { |
151 |
| - logger.debug("Failing test(s): {}\n{}", sourceLocation, firstFailures); |
| 141 | + private boolean isSynthesisPossible(final Result firstResultWithFalse, final Result secondResultWithTrue) { |
| 142 | + // this method is a key optimization in Nopol |
| 143 | + // it enables to not start the synthesis when we are sure that it is not possible |
| 144 | + // only based on the observed test outcomes with angelic values |
| 145 | + |
| 146 | + Collection<Description> testFailuresWithFalse = TestSuiteExecution.collectDescription(firstResultWithFalse.getFailures()); |
| 147 | + Collection<Description> testFailuresWithTrue = TestSuiteExecution.collectDescription(secondResultWithTrue.getFailures()); |
| 148 | + |
| 149 | + // contract: all test failures must either in testFailuresWithFalse or in secondFailures |
| 150 | + // removes from testFailuresWithFalse all of its elements that are not contained in testFailuresWithTrue |
| 151 | + // consequently, it remains the elements that are always failing |
| 152 | + Collection<Description> testsThatAreAlwasyFailing = new ArrayList<>(testFailuresWithFalse); |
| 153 | + testsThatAreAlwasyFailing.retainAll(testFailuresWithTrue); |
| 154 | + |
| 155 | + boolean synthesisIsPossible = testsThatAreAlwasyFailing.isEmpty(); |
| 156 | + |
| 157 | + // some logging |
| 158 | + int nbFirstSuccess = firstResultWithFalse.getRunCount() - firstResultWithFalse.getFailureCount(); |
| 159 | + int nbSecondSuccess = secondResultWithTrue.getRunCount() - secondResultWithTrue.getFailureCount(); |
| 160 | + if (!synthesisIsPossible || (nbFirstSuccess == 0 && nbSecondSuccess == 0)) { |
152 | 161 | Logger testsOutput = LoggerFactory.getLogger("tests.output");
|
153 |
| - testsOutput.debug("First set: \n{}", firstResult.getFailures()); |
154 |
| - testsOutput.debug("Second set: \n{}", secondResult.getFailures()); |
| 162 | + testsOutput.debug("Failing tests with false: \n{}", firstResultWithFalse.getFailures()); |
| 163 | + testsOutput.debug("Failing tests with true: \n{}", secondResultWithTrue.getFailures()); |
155 | 164 | }
|
156 |
| - return viablePatch; |
| 165 | + return synthesisIsPossible; |
157 | 166 | }
|
158 | 167 |
|
159 |
| - /** |
160 |
| - * @see InstrumentedProgram#isAViablePatch() |
161 |
| - */ |
162 |
| - public boolean isAViablePatch() { |
163 |
| - return viablePatch; |
164 |
| - } |
165 | 168 | }
|
0 commit comments