Skip to content

Commit

Permalink
Merge pull request #1246 from hcoles/feature/faster_incremental_analysis
Browse files Browse the repository at this point in the history
prioritise previous killing test
  • Loading branch information
hcoles authored Aug 15, 2023
2 parents 88f2b49 + 07e3472 commit 4ae57ec
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ public IncrementalAnalyser(CodeHistory history, CoverageDatabase coverage, boole
}

@Override
public Collection<MutationResult> analyse(
final Collection<MutationDetails> mutation) {
public Collection<MutationResult> analyse(Collection<MutationDetails> mutation) {

final List<MutationResult> mrs = new ArrayList<>(
mutation.size());
Expand Down Expand Up @@ -81,12 +80,14 @@ private void logTotals() {
LOG.info("Incremental analysis reduced number of mutations by " + numberOfReducedMutations );
}

private MutationResult analyseFromHistory(final MutationDetails each,
final MutationStatusTestPair mutationStatusTestPair) {
private MutationResult analyseFromHistory(MutationDetails each, MutationStatusTestPair mutationStatusTestPair) {

final ClassName clazz = each.getClassName();

if (this.history.hasClassChanged(clazz)) {
if (mutationStatusTestPair.getKillingTest().isPresent()) {
return prioritiseLastTest(each, mutationStatusTestPair.getKillingTest().get());
}
return analyseFromScratch(each);
}

Expand All @@ -103,6 +104,10 @@ private MutationResult analyseFromHistory(final MutationDetails each,
DetectionStatus.KILLED,
killingTestNames,
mutationStatusTestPair.getSucceedingTests());
} else {
if (mutationStatusTestPair.getKillingTest().isPresent()) {
return prioritiseLastTest(each, mutationStatusTestPair.getKillingTest().get());
}
}
}

Expand All @@ -114,7 +119,6 @@ private MutationResult analyseFromHistory(final MutationDetails each,

return analyseFromScratch(each);
}

private List<String> filterUnchangedKillingTests(final MutationDetails each,
final MutationStatusTestPair mutationStatusTestPair) {

Expand All @@ -134,6 +138,25 @@ private static Predicate<TestInfo> isAKillingTestFor(final MutationStatusTestPai
return a -> killingTestNames.contains(a.getName());
}

private MutationResult prioritiseLastTest(MutationDetails mutation, String killingTestName) {
List<TestInfo> mutableOrderedTestList = mutation.getTestsInOrder();

Optional<TestInfo> maybeKillingTest = mutation.getTestsInOrder().stream()
.filter(ti -> ti.getName().equals(killingTestName))
.findFirst();

// last killing test is no longer available
if (!maybeKillingTest.isPresent()) {
return analyseFromScratch(mutation);
}

// hack the ordered list to put the killing test at the front
mutableOrderedTestList.remove(maybeKillingTest.get());
mutableOrderedTestList.add(0, maybeKillingTest.get());

return analyseFromScratch(mutation);
}

private MutationResult analyseFromScratch(final MutationDetails mutation) {
return makeResult(mutation, DetectionStatus.NOT_STARTED);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.pitest.mutationtest.DetectionStatus.KILLED;
Expand All @@ -19,6 +19,7 @@

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
Expand All @@ -29,6 +30,7 @@

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.junit.After;
import org.junit.Before;
Expand Down Expand Up @@ -241,6 +243,54 @@ public void shouldStartPreviousKilledMutationsAtAStatusOfNotStartedWhenTestHasCh
));
}

@Test
public void prioritisesLastKillingTestWhenClassHasChanged() {

final String killingTest = "fooTest";
setHistoryForAllMutationsTo(DetectionStatus.KILLED, killingTest);
Collection<TestInfo> tests = Arrays.asList(testNamed("one"), testNamed("two"), testNamed(killingTest), testNamed("three"));

final MutationDetails md = makeMutation("foo");
md.addTestsInOrder(tests);

when(this.coverage.getTestsForClass(any(ClassName.class)))
.thenReturn(tests);
when(this.history.hasClassChanged(ClassName.fromString("clazz"))).thenReturn(
true);
when(this.history.hasClassChanged(ClassName.fromString("TEST_CLASS")))
.thenReturn(false);

MutationResult actual = this.testee.analyse(singletonList(md)).stream()
.findFirst().get();

assertThat(actual.getDetails().getTestsInOrder().get(0), Matchers.equalTo(testNamed(killingTest)));
assertThat(actual.getDetails().getTestsInOrder(), Matchers.hasSize(4));
}

@Test
public void prioritisesLastKillingTestWhenTestHasChanged() {

final String killingTest = "fooTest";
setHistoryForAllMutationsTo(DetectionStatus.KILLED, killingTest);
Collection<TestInfo> tests = Arrays.asList(testNamed("one"), testNamed("two"), testNamed(killingTest), testNamed("three"));

final MutationDetails md = makeMutation("foo");
md.addTestsInOrder(tests);

when(this.coverage.getTestsForClass(any(ClassName.class)))
.thenReturn(tests);
when(this.history.hasClassChanged(ClassName.fromString("clazz"))).thenReturn(
false);
when(this.history.hasClassChanged(ClassName.fromString("TEST_CLASS")))
.thenReturn(true);

MutationResult actual = this.testee.analyse(singletonList(md)).stream()
.findFirst().get();

assertThat(actual.getDetails().getTestsInOrder().get(0), Matchers.equalTo(testNamed(killingTest)));
assertThat(actual.getDetails().getTestsInOrder(), Matchers.hasSize(4));
}

@Test
public void assessMultipleMutationsAtATime() {
final MutationDetails md1 = makeMutation("foo");
Expand Down Expand Up @@ -299,6 +349,11 @@ public void assessMultipleMutationsAtATime() {
));
}

private TestInfo testNamed(String name) {
return new TestInfo(
"TEST_CLASS", name, 0, Optional.empty(), 0);
}

private Matcher<MutationResult> withStatus(final DetectionStatus status) {
return new TypeSafeDiagnosingMatcher<MutationResult>() {

Expand Down

0 comments on commit 4ae57ec

Please sign in to comment.