Skip to content

Commit

Permalink
Merge pull request #1251 from hcoles/feature/pluggable_history
Browse files Browse the repository at this point in the history
Feature/pluggable history
  • Loading branch information
hcoles authored Sep 19, 2023
2 parents 3e38926 + 209b9d1 commit 3638a83
Show file tree
Hide file tree
Showing 66 changed files with 1,082 additions and 511 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
23 changes: 17 additions & 6 deletions pitest-entry/src/main/java/org/pitest/classpath/CodeSource.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
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;

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();

default Set<ClassName> getAllClassAndTestNames() {
final Set<ClassName> names = new HashSet<>();
names.addAll(getCodeUnderTestNames());
names.addAll(getTestClassNames());
return names;
}

Set<ClassName> getCodeUnderTestNames();

Set<ClassName> getTestClassNames();

Stream<ClassTree> testTrees();

ClassPath getClassPath();
Expand All @@ -28,10 +38,11 @@ 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);

}
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 All @@ -93,7 +93,13 @@ public CoverageData calculateCoverage() {
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);
Expand Down Expand Up @@ -154,10 +160,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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.Serializable;
import java.util.Objects;
import java.util.StringJoiner;

import org.pitest.classinfo.ClassName;
import org.pitest.classinfo.HierarchicalClassId;
Expand Down Expand Up @@ -47,4 +48,12 @@ public boolean equals(final Object obj) {
return Objects.equals(id, other.id)
&& Objects.equals(coverageId, other.coverageId);
}

@Override
public String toString() {
return new StringJoiner(", ", ClassHistory.class.getSimpleName() + "[", "]")
.add("id=" + id)
.add("coverageId='" + coverageId + "'")
.toString();
}
}
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.Comparator;
import java.util.List;
import java.util.stream.Collectors;

Expand All @@ -9,7 +10,14 @@ public class CompoundMutationResultInterceptor implements MutationResultIntercep
private final List<MutationResultInterceptor> interceptors;

public CompoundMutationResultInterceptor(List<MutationResultInterceptor> interceptors) {
this.interceptors = interceptors;
this.interceptors = interceptors.stream()
.sorted(Comparator.comparing(MutationResultInterceptor::priority))
.collect(Collectors.toList());
}

public CompoundMutationResultInterceptor add(MutationResultInterceptor extra) {
interceptors.add(0, extra);
return this;
}

@Override
Expand Down
Loading

0 comments on commit 3638a83

Please sign in to comment.