diff --git a/pitest-entry/src/main/java/org/pitest/classpath/CodeSource.java b/pitest-entry/src/main/java/org/pitest/classpath/CodeSource.java index 45c7c8474..6bece2ae4 100644 --- a/pitest-entry/src/main/java/org/pitest/classpath/CodeSource.java +++ b/pitest-entry/src/main/java/org/pitest/classpath/CodeSource.java @@ -1,6 +1,7 @@ package org.pitest.classpath; import java.util.Collection; +import java.util.HashSet; import java.util.Optional; import java.util.Set; import java.util.stream.Stream; @@ -18,6 +19,13 @@ public interface CodeSource extends ClassHashSource, ClassByteArraySource { Stream codeTrees(); + default Set getAllClassAndTestNames() { + final Set names = new HashSet<>(); + names.addAll(getCodeUnderTestNames()); + names.addAll(getTestClassNames()); + return names; + } + Set getCodeUnderTestNames(); Set getTestClassNames(); @@ -31,8 +39,10 @@ public interface CodeSource extends ClassHashSource, ClassByteArraySource { Optional fetchClassBytes(ClassName clazz); Optional fetchClassHash(ClassName clazz); + Collection fetchClassHashes(Collection classes); @Override Optional getBytes(String clazz); + } diff --git a/pitest-entry/src/main/java/org/pitest/coverage/execute/DefaultCoverageGenerator.java b/pitest-entry/src/main/java/org/pitest/coverage/execute/DefaultCoverageGenerator.java index fcb067c32..14f505656 100644 --- a/pitest-entry/src/main/java/org/pitest/coverage/execute/DefaultCoverageGenerator.java +++ b/pitest-entry/src/main/java/org/pitest/coverage/execute/DefaultCoverageGenerator.java @@ -93,7 +93,13 @@ public CoverageData calculateCoverage(Predicate testFilter) { this.code)); this.timings.registerStart(Timings.Stage.COVERAGE); - gatherCoverageData(tests, coverage); + if (tests.isEmpty()) { + // This may happen as a result of filtering for incremental analysis as well as + // simple misconfiguration. + LOG.info("No test classes identified to scan"); + } else { + gatherCoverageData(tests, coverage); + } this.timings.registerEnd(Timings.Stage.COVERAGE); final long time = NANOSECONDS.toSeconds(System.nanoTime() - t0); 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 32f774709..7b52dc89a 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/History.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/History.java @@ -1,11 +1,9 @@ package org.pitest.mutationtest; import org.pitest.classinfo.ClassName; -import org.pitest.classinfo.HierarchicalClassId; import org.pitest.coverage.CoverageDatabase; import org.pitest.mutationtest.engine.MutationDetails; -import java.util.Collection; import java.util.List; import java.util.function.Predicate; @@ -17,8 +15,6 @@ default Predicate limitTests() { } void processCoverage(CoverageDatabase coverageData); - void recordClassPath(Collection ids, CoverageDatabase coverageInfo); - List analyse(List mutationsForClasses); void recordResult(MutationResult result); diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/NullHistory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/NullHistory.java index e982ea94b..be9f74499 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/NullHistory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/NullHistory.java @@ -1,10 +1,8 @@ package org.pitest.mutationtest.incremental; -import java.util.Collection; import java.util.Collections; import java.util.List; -import org.pitest.classinfo.HierarchicalClassId; import org.pitest.coverage.CoverageDatabase; import org.pitest.mutationtest.History; import org.pitest.mutationtest.MutationResult; @@ -36,10 +34,4 @@ public void close() { } - @Override - public void recordClassPath(final Collection ids, - final CoverageDatabase coverageInfo) { - - } - } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/ObjectOutputStreamHistory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/ObjectOutputStreamHistory.java index 168695fec..b1a510ca7 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/ObjectOutputStreamHistory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/ObjectOutputStreamHistory.java @@ -10,17 +10,21 @@ import java.io.Reader; import java.io.Serializable; import java.util.Base64; -import java.util.Collection; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.logging.Logger; +import org.pitest.classinfo.ClassHash; import org.pitest.classinfo.ClassName; import org.pitest.classinfo.HierarchicalClassId; import org.pitest.classpath.CodeSource; import org.pitest.coverage.CoverageDatabase; import java.util.Optional; +import java.util.stream.Collectors; + import org.pitest.mutationtest.ClassHistory; import org.pitest.mutationtest.History; import org.pitest.mutationtest.MutationAnalyser; @@ -55,19 +59,6 @@ private BufferedReader createReader(Optional input) { .orElse(null); } - @Override - public void recordClassPath(final Collection ids, - final CoverageDatabase coverageInfo) { - final PrintWriter output = this.outputFactory.create(); - output.println(ids.size()); - for (final HierarchicalClassId each : ids) { - final ClassHistory coverage = new ClassHistory(each, - coverageInfo.getCoverageIdForClass(each.getName()).toString(16)); - output.println(serialize(coverage)); - } - output.flush(); - } - @Override public void recordResult(final MutationResult result) { final PrintWriter output = this.outputFactory.create(); @@ -104,8 +95,29 @@ public void initialize() { @Override public void processCoverage(CoverageDatabase coverageData) { this.coverageData = coverageData; + recordClassPath(coverageData); } + private void recordClassPath(CoverageDatabase coverageData) { + Set allClassNames = code.getAllClassAndTestNames(); + + // sort by classname to ensure order consistent across machines + List ids = this.code.fetchClassHashes(allClassNames).stream() + .map(ClassHash::getHierarchicalId) + .sorted(Comparator.comparing(HierarchicalClassId::getName)) + .collect(Collectors.toList()); + + final PrintWriter output = this.outputFactory.create(); + output.println(ids.size()); + for (final HierarchicalClassId each : ids) { + final ClassHistory coverage = new ClassHistory(each, + coverageData.getCoverageIdForClass(each.getName()).toString(16)); + output.println(serialize(coverage)); + } + output.flush(); + } + + private void restoreResults() { String line; try { 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 fbd61100f..1e81dbd95 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 @@ -16,9 +16,7 @@ import org.pitest.classinfo.CachingByteArraySource; import org.pitest.classinfo.ClassByteArraySource; -import org.pitest.classinfo.ClassHash; import org.pitest.classinfo.ClassName; -import org.pitest.classinfo.HierarchicalClassId; import org.pitest.classpath.ClassPathByteArraySource; import org.pitest.classpath.ClassloaderByteArraySource; import org.pitest.classpath.CodeSource; @@ -62,8 +60,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; @@ -167,8 +163,6 @@ private CombinedStatistics runAnalysis(Runtime runtime, long t0, EngineArguments LOG.info("Created " + tus.size() + " mutation test units" ); - recordClassPath(history, coverageData); - LOG.fine("Used memory before analysis start " + ((runtime.totalMemory() - runtime.freeMemory()) / MB) + " mb"); LOG.fine("Free Memory before analysis start " + (runtime.freeMemory() / MB) @@ -285,25 +279,6 @@ private MutationResultInterceptor resultInterceptor() { return this.strategies.resultInterceptor(); } - private void recordClassPath(History history, CoverageDatabase coverageData) { - Set allClassNames = getAllClassesAndTests(); - - // sort by classname to ensure order consistent across machines - List ids = this.code.fetchClassHashes(allClassNames).stream() - .map(ClassHash::getHierarchicalId) - .sorted(Comparator.comparing(HierarchicalClassId::getName)) - .collect(Collectors.toList()); - - history.recordClassPath(ids, coverageData); - } - - private Set getAllClassesAndTests() { - final Set names = new HashSet<>(); - names.addAll(code.getCodeUnderTestNames()); - names.addAll(code.getTestClassNames()); - return names; - } - private List verifyBuildSuitableForMutationTesting() { return this.strategies.buildVerifier().verify(); } @@ -368,9 +343,6 @@ private List buildMutationTests(CoverageDatabase coverageD final MutationSource source = new MutationSource(mutationConfig, testPrioritiser, bas, interceptor); - // final MutationAnalyser analyser = new IncrementalAnalyser(new DefaultCodeHistory(this.code, history), - // coverageData, - // enableIncrementalAnalysisLogging(history)); final WorkerFactory wf = new WorkerFactory(this.baseDir, coverage() .getConfiguration(), mutationConfig, args, diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/ObjectOutputStreamHistoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/ObjectOutputStreamHistoryTest.java index b7a736de7..125d36505 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/ObjectOutputStreamHistoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/ObjectOutputStreamHistoryTest.java @@ -22,12 +22,15 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.pitest.classinfo.ClassHash; import org.pitest.classinfo.ClassIdentifier; import org.pitest.classinfo.ClassName; import org.pitest.classinfo.HierarchicalClassId; import org.pitest.classpath.CodeSource; import org.pitest.coverage.CoverageDatabase; import java.util.Optional; +import java.util.stream.Collectors; + import org.pitest.mutationtest.ClassHistory; import org.pitest.mutationtest.DetectionStatus; import org.pitest.mutationtest.MutationResult; @@ -148,8 +151,31 @@ private void recordClassPathWithTestee( final HierarchicalClassId... classIdentifiers) { this.testee = new ObjectOutputStreamHistory(this.code, this.writerFactory, Optional. empty()); - final Collection ids = Arrays.asList(classIdentifiers); - this.testee.recordClassPath(ids, this.coverage); + final Collection ids = Arrays.asList(classIdentifiers).stream() + .map(id -> new ClassHash() { + @Override + public ClassIdentifier getId() { + return id.getId(); + } + + @Override + public ClassName getName() { + return id.getName(); + } + + @Override + public BigInteger getDeepHash() { + return BigInteger.ZERO; + } + + @Override + public HierarchicalClassId getHierarchicalId() { + return id; + } + }).collect(Collectors.toList()); + + when(code.fetchClassHashes(any(Collection.class))).thenReturn(ids); + this.testee.processCoverage(this.coverage); } } 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 05b08355d..3318c8b74 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 @@ -14,7 +14,6 @@ */ package org.pitest.mutationtest.tooling; -import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyCollection; @@ -164,33 +163,7 @@ public void shouldRecordClassPath() { createAndRunTestee(); - verify(this.history).recordClassPath(asList(fooId), this.coverageDb); - } - - @Test - public void ordersHistoryEntries() { - - final ClassName clazz = ClassName.fromClass(Foo.class); - - final HierarchicalClassId fooId = new HierarchicalClassId( - new ClassIdentifier(0, clazz), "0"); - final HierarchicalClassId barId = new HierarchicalClassId( - new ClassIdentifier(0, ClassName.fromString("Bar")), "0"); - final ClassInfo foo = ClassInfoMother.make(fooId.getId()); - final ClassInfo bar = ClassInfoMother.make(barId.getId()); - - when(this.mutater.findMutations(ClassName.fromClass(Foo.class))).thenReturn(aMutantIn(Foo.class)); - - when(this.code.getCodeUnderTestNames()).thenReturn( - Collections.singleton(clazz)); - when(this.code.fetchClassHashes(anyCollection())).thenReturn( - asList(foo, bar)); - when(this.coverageDb.getCodeLinesForClass(clazz)).thenReturn(new ClassLines(clazz, Collections.emptySet())); - - createAndRunTestee(); - - // bar comes first alphabetically - verify(this.history).recordClassPath(asList(barId, fooId), this.coverageDb); + verify(this.history).processCoverage(this.coverageDb); } @Test