diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/History.java b/pitest-entry/src/main/java/org/pitest/mutationtest/History.java index 7b52dc89a..4eda97934 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/History.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/History.java @@ -10,9 +10,16 @@ public interface History { void initialize(); + + default Predicate limitTests(List mutants) { + return limitTests(); + } + + @Deprecated default Predicate limitTests() { return c -> true; } + void processCoverage(CoverageDatabase coverageData); List analyse(List mutationsForClasses); diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/build/DryRunUnit.java b/pitest-entry/src/main/java/org/pitest/mutationtest/build/DryRunUnit.java index 18a33e9e8..19c8cf6f2 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/build/DryRunUnit.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/build/DryRunUnit.java @@ -42,4 +42,9 @@ public int priority() { return Integer.MAX_VALUE; } + @Override + public Collection mutants() { + return mutations; + } + } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/build/KnownStatusMutationTestUnit.java b/pitest-entry/src/main/java/org/pitest/mutationtest/build/KnownStatusMutationTestUnit.java index 6fb624ca7..e66c652af 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/build/KnownStatusMutationTestUnit.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/build/KnownStatusMutationTestUnit.java @@ -1,10 +1,13 @@ package org.pitest.mutationtest.build; +import java.util.Collection; import java.util.List; import java.util.logging.Logger; +import java.util.stream.Collectors; import org.pitest.mutationtest.MutationMetaData; import org.pitest.mutationtest.MutationResult; +import org.pitest.mutationtest.engine.MutationDetails; import org.pitest.util.Log; public class KnownStatusMutationTestUnit implements MutationAnalysisUnit { @@ -30,4 +33,11 @@ public int priority() { return Integer.MAX_VALUE; } + @Override + public Collection mutants() { + return mutations.stream() + .map(MutationResult::getDetails) + .collect(Collectors.toList()); + } + } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/build/MutationAnalysisUnit.java b/pitest-entry/src/main/java/org/pitest/mutationtest/build/MutationAnalysisUnit.java index 84ce45e9f..aaad6aeea 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/build/MutationAnalysisUnit.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/build/MutationAnalysisUnit.java @@ -1,8 +1,10 @@ package org.pitest.mutationtest.build; +import java.util.Collection; import java.util.concurrent.Callable; import org.pitest.mutationtest.MutationMetaData; +import org.pitest.mutationtest.engine.MutationDetails; /** * A unit of mutation analysis @@ -11,4 +13,5 @@ public interface MutationAnalysisUnit extends Callable { int priority(); + Collection mutants(); } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/build/MutationTestUnit.java b/pitest-entry/src/main/java/org/pitest/mutationtest/build/MutationTestUnit.java index 086793cab..824199143 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/build/MutationTestUnit.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/build/MutationTestUnit.java @@ -62,6 +62,11 @@ public int priority() { return this.availableMutations.size(); } + @Override + public Collection mutants() { + return availableMutations; + } + private void runTestsInSeperateProcess(final MutationStatusMap mutations) throws IOException, InterruptedException { while (mutations.hasUnrunMutations()) { diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java index c90acc91f..3533b4375 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java @@ -43,6 +43,7 @@ import org.pitest.mutationtest.build.WorkerFactory; import org.pitest.mutationtest.config.ReportOptions; import org.pitest.mutationtest.config.SettingsFactory; +import org.pitest.mutationtest.engine.MutationDetails; import org.pitest.mutationtest.engine.MutationEngine; import org.pitest.mutationtest.execute.MutationAnalysisExecutor; import org.pitest.mutationtest.incremental.HistoryListener; @@ -133,7 +134,15 @@ public CombinedStatistics runReport() throws IOException { return emptyStatistics(); } - return runAnalysis(runtime, t0, args, engine, issues); + // Extract mutants from analysis units. Advanced history implementations can + // use this data to reduce the number of tests run during coverage. + // This is list of mutants is potentially larger than the one finally + // assessed, as no filters have been run across it. + List unfilteredMutants = preScanMutations.stream() + .flatMap(unit -> unit.mutants().stream()) + .collect(Collectors.toList()); + + return runAnalysis(runtime, t0, args, engine, issues, unfilteredMutants); } @@ -142,11 +151,11 @@ private CombinedStatistics emptyStatistics() { return new CombinedStatistics(mutationStatistics, new CoverageSummary(0,0), Collections.emptyList()); } - private CombinedStatistics runAnalysis(Runtime runtime, long t0, EngineArguments args, MutationEngine engine, List issues) { + private CombinedStatistics runAnalysis(Runtime runtime, long t0, EngineArguments args, MutationEngine engine, List issues, List unfilteredMutants) { History history = this.strategies.history(); history.initialize(); - CoverageDatabase coverageData = coverage().calculateCoverage(history.limitTests()); + CoverageDatabase coverageData = coverage().calculateCoverage(history.limitTests(unfilteredMutants)); history.processCoverage(coverageData); LOG.fine("Used memory after coverage calculation " diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/build/AnalyisPriorityComparatorTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/build/AnalyisPriorityComparatorTest.java index fe54cea06..efed31552 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/build/AnalyisPriorityComparatorTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/build/AnalyisPriorityComparatorTest.java @@ -3,10 +3,13 @@ import static org.junit.Assert.assertEquals; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; import org.junit.Test; import org.pitest.mutationtest.MutationMetaData; +import org.pitest.mutationtest.engine.MutationDetails; public class AnalyisPriorityComparatorTest { @@ -50,6 +53,11 @@ public MutationMetaData call() throws Exception { return null; } + @Override + public Collection mutants() { + return Collections.emptyList(); + } + }; } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/MutationCoverageReportTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/MutationCoverageReportTest.java index f4ea301f1..d2dc45cc3 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/MutationCoverageReportTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/MutationCoverageReportTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyCollection; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -112,7 +113,7 @@ public void setUp() { when( this.listenerFactory.getListener(any(), any(ListenerArguments.class))).thenReturn(this.listener); - when(history.limitTests()).thenReturn(c -> true); + when(history.limitTests(anyList())).thenReturn(c -> true); mockMutationEngine(); }