Skip to content

Commit

Permalink
combine history store and incremental analyser
Browse files Browse the repository at this point in the history
Concentrates incremental analysis concern behind a single interface so
implementations are not limited by the implementation details of the
default history store. Allows more information to be stored within
history.
  • Loading branch information
hcoles committed Sep 13, 2023
1 parent 4c6f0dd commit 9b16f0d
Show file tree
Hide file tree
Showing 55 changed files with 789 additions and 417 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public void testCreateCodeSource() {
final CodeSource source = this.underTest.createCodeSource();
assertNotNull(source);

assertTrue(source.fetchClass(ClassName.fromClass(CodeSourceAggregator.class)).isPresent());
assertFalse(source.fetchClass(ClassName.fromString("com.doesnt.exist.Type")).isPresent());
assertTrue(source.fetchClassHash(ClassName.fromClass(CodeSourceAggregator.class)).isPresent());
assertFalse(source.fetchClassHash(ClassName.fromString("com.doesnt.exist.Type")).isPresent());
}

}
15 changes: 15 additions & 0 deletions pitest-entry/src/main/java/org/pitest/classinfo/ClassHash.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.pitest.classinfo;

import java.math.BigInteger;

public interface ClassHash {

ClassIdentifier getId();

ClassName getName();

BigInteger getDeepHash();

HierarchicalClassId getHierarchicalId();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.pitest.classinfo;

import java.util.Optional;

public interface ClassHashSource {
Optional<ClassHash> fetchClassHash(ClassName name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,22 @@
* a class between runs are tracked by calculating the hash of its bytecode and the
* bytecode of classes it has a strong relationship to.
*/
public final class ClassInfo {
public final class ClassInfo implements ClassHash {

private final ClassIdentifier id;
private final ClassPointer outerClass;
private final ClassPointer superClass;

public ClassInfo(ClassPointer superClass, ClassPointer outerClass, ClassInfoBuilder builder) {
this(superClass, outerClass, builder.id);
}

public ClassInfo(ClassPointer superClass, ClassPointer outerClass, ClassIdentifier id) {
this.superClass = superClass;
this.outerClass = outerClass;
this.id = builder.id;
this.id = id;
}

public ClassIdentifier getId() {
return this.id;
}
Expand Down

This file was deleted.

This file was deleted.

17 changes: 9 additions & 8 deletions pitest-entry/src/main/java/org/pitest/classinfo/Repository.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import java.util.Optional;

public class Repository implements ClassInfoSource {
public class Repository implements ClassHashSource {

private final HashFunction hashFunction;
private final Map<ClassName, ClassInfo> knownClasses = new HashMap<>();
Expand All @@ -41,17 +41,18 @@ public boolean hasClass(final ClassName name) {
return this.knownClasses.containsKey(name) || querySource(name).isPresent();
}

public Optional<ClassInfo> fetchClass(final Class<?> clazz) { // NO_UCD (test
// only)
return fetchClass(clazz.getName());
@Override
public Optional<ClassHash> fetchClassHash(final ClassName clazz) {
return this.fetchClass(clazz)
.map(ClassHash.class::cast);
}

private Optional<ClassInfo> fetchClass(final String name) {
return fetchClass(ClassName.fromString(name));
Optional<ClassInfo> fetchClass(final Class<?> clazz) { // NO_UCD (test
// only)
return fetchClass(ClassName.fromClass(clazz));
}

@Override
public Optional<ClassInfo> fetchClass(final ClassName name) {
Optional<ClassInfo> fetchClass(final ClassName name) {
final ClassInfo info = this.knownClasses.get(name);
if (info != null) {
return Optional.ofNullable(info);
Expand Down
13 changes: 7 additions & 6 deletions pitest-entry/src/main/java/org/pitest/classpath/CodeSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@

import org.pitest.bytecode.analysis.ClassTree;
import org.pitest.classinfo.ClassByteArraySource;
import org.pitest.classinfo.ClassInfo;
import org.pitest.classinfo.ClassInfoSource;
import org.pitest.classinfo.ClassHash;
import org.pitest.classinfo.ClassHashSource;
import org.pitest.classinfo.ClassName;

/**
* Provides access to code and tests on the classpath
*/
public interface CodeSource extends ClassInfoSource, ClassByteArraySource {
public interface CodeSource extends ClassHashSource, ClassByteArraySource {

Stream<ClassTree> codeTrees();

Set<ClassName> getCodeUnderTestNames();

Set<ClassName> getTestClassNames();

Stream<ClassTree> testTrees();

ClassPath getClassPath();
Expand All @@ -28,9 +30,8 @@ public interface CodeSource extends ClassInfoSource, ClassByteArraySource {

Optional<byte[]> fetchClassBytes(ClassName clazz);

@Override
Optional<ClassInfo> fetchClass(ClassName clazz);
Collection<ClassInfo> getClassInfo(Collection<ClassName> classes);
Optional<ClassHash> fetchClassHash(ClassName clazz);
Collection<ClassHash> fetchClassHashes(Collection<ClassName> classes);

@Override
Optional<byte[]> getBytes(String clazz);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package org.pitest.classpath;

import org.pitest.bytecode.analysis.ClassTree;
import org.pitest.classinfo.ClassInfo;
import org.pitest.classinfo.ClassHash;
import org.pitest.classinfo.ClassName;
import org.pitest.classinfo.NameToClassInfo;
import org.pitest.classinfo.Repository;
import org.pitest.classinfo.TestToClassMapper;
import org.pitest.functional.Streams;

import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -41,6 +39,10 @@ public Set<ClassName> getCodeUnderTestNames() {
return this.classPath.code().stream().collect(Collectors.toSet());
}

public Set<ClassName> getTestClassNames() {
return this.classPath.test().stream().collect(Collectors.toSet());
}

public Stream<ClassTree> testTrees() {
return this.classPath.test().stream()
.map(c -> this.getBytes(c.asJavaName()))
Expand All @@ -58,9 +60,9 @@ public Optional<ClassName> findTestee(final String className) {
return mapper.findTestee(className);
}

public Collection<ClassInfo> getClassInfo(final Collection<ClassName> classes) {
public Collection<ClassHash> fetchClassHashes(final Collection<ClassName> classes) {
return classes.stream()
.flatMap(nameToClassInfo())
.flatMap(c -> Streams.fromOptional(classRepository.fetchClassHash(c)))
.collect(Collectors.toList());
}

Expand All @@ -69,13 +71,8 @@ public Optional<byte[]> fetchClassBytes(final ClassName clazz) {
}

@Override
public Optional<ClassInfo> fetchClass(final ClassName clazz) {
return this.classRepository.fetchClass(clazz);
}

private Function<ClassName, Stream<ClassInfo>> nameToClassInfo() {
return new NameToClassInfo(this.classRepository)
.andThen(Streams::fromOptional);
public Optional<ClassHash> fetchClassHash(final ClassName clazz) {
return this.classRepository.fetchClassHash(clazz);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

package org.pitest.coverage;

import org.pitest.classinfo.ClassInfo;
import org.pitest.classinfo.ClassHash;
import org.pitest.classinfo.ClassName;
import org.pitest.classpath.CodeSource;
import org.pitest.testapi.Description;
Expand Down Expand Up @@ -147,7 +147,7 @@ private BigInteger generateCoverageNumber(Collection<TestInfo> coverage) {
.map(TestInfo.toDefiningClassName())
.collect(Collectors.toSet());

for (final ClassInfo each : this.code.getClassInfo(testClasses)) {
for (final ClassHash each : this.code.fetchClassHashes(testClasses)) {
coverageNumber = coverageNumber.add(each.getDeepHash());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@

package org.pitest.coverage;

import org.pitest.classinfo.ClassName;
import org.pitest.mutationtest.config.TestPluginArguments;
import org.pitest.process.LaunchOptions;

import java.util.function.Predicate;

public interface CoverageGenerator {

CoverageDatabase calculateCoverage();
CoverageDatabase calculateCoverage(Predicate<ClassName> testFilter);

TestPluginArguments getConfiguration();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package org.pitest.coverage.execute;

import org.pitest.bytecode.analysis.ClassTree;
import org.pitest.classinfo.ClassInfo;
import org.pitest.classinfo.ClassName;
import org.pitest.classpath.CodeSource;
import org.pitest.coverage.CoverageData;
Expand Down Expand Up @@ -45,7 +44,7 @@
import java.net.ServerSocket;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.logging.Logger;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -77,13 +76,14 @@ public DefaultCoverageGenerator(final File workingDir,
}

@Override
public CoverageData calculateCoverage() {
public CoverageData calculateCoverage(Predicate<ClassName> testFilter) {
try {
final long t0 = System.nanoTime();

this.timings.registerStart(Timings.Stage.SCAN_CLASS_PATH);
List<String> tests = this.code.testTrees()
.map(ClassTree::name)
.filter(testFilter)
.map(ClassName::asInternalName)
.collect(Collectors.toList());

Expand Down Expand Up @@ -154,10 +154,6 @@ private void gatherCoverageData(List<String> tests,
}
}

private static Function<ClassInfo, String> classInfoToName() {
return a -> a.getName().asInternalName();
}

private Consumer<String> captureStandardOutIfVerbose() {
if (this.verbosity.showMinionOutput()) {
return log();
Expand Down
28 changes: 28 additions & 0 deletions pitest-entry/src/main/java/org/pitest/mutationtest/History.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
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;

public interface History {

void initialize();
default Predicate<ClassName> limitTests() {
return c -> true;
}
void processCoverage(CoverageDatabase coverageData);

void recordClassPath(Collection<HierarchicalClassId> ids, CoverageDatabase coverageInfo);

List<MutationResult> analyse(List<MutationDetails> mutationsForClasses);

void recordResult(MutationResult result);

void close();

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package org.pitest.mutationtest;

import org.pitest.classpath.CodeSource;
import org.pitest.mutationtest.incremental.WriterFactory;
import org.pitest.plugin.ToolClasspathPlugin;

import java.io.Reader;
import java.util.Optional;

public interface HistoryFactory extends ToolClasspathPlugin {
HistoryStore makeHistory(WriterFactory output, Optional<Reader> input);
History makeHistory(CodeSource code, WriterFactory output, Optional<Reader> input);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.pitest.mutationtest;

import java.util.Collection;
import java.util.List;

import org.pitest.mutationtest.engine.MutationDetails;

Expand All @@ -9,7 +10,6 @@
*/
public interface MutationAnalyser {

Collection<MutationResult> analyse(
Collection<MutationDetails> mutationsForClasses);
List<MutationResult> analyse(Collection<MutationDetails> mutationsForClasses);

}
Loading

0 comments on commit 9b16f0d

Please sign in to comment.