Skip to content

Commit

Permalink
Change detector minimization (#354)
Browse files Browse the repository at this point in the history
* test: add a test on ChangeMinimizer

* feat: add ChangeMinimizer, that will keep assertion that make the test fail

* docs: add todos and docs

* test: remove all useless call to reset()

* checkstyle: remove unused imports
  • Loading branch information
danglotb authored Mar 9, 2018
1 parent ece2fe8 commit ddf3c97
Show file tree
Hide file tree
Showing 18 changed files with 228 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import fr.inria.diversify.utils.Initializer;
import fr.inria.diversify.utils.sosiefier.InputConfiguration;
import fr.inria.diversify.utils.sosiefier.InputProgram;
import fr.inria.stamp.minimization.GeneralMinimizer;
import fr.inria.stamp.minimization.ChangeMinimizer;
import fr.inria.stamp.minimization.Minimizer;
import fr.inria.stamp.test.launcher.TestLauncher;
import fr.inria.stamp.test.listener.TestListener;
Expand Down Expand Up @@ -66,7 +66,7 @@ public void init(InputConfiguration configuration) {
DSpotUtils.shouldAddSeparator.apply(pathToFolder)
: "");
inputProgram.setProgramDir(this.pathToChangedVersionOfProgram);
Initializer.initialize(configuration, inputProgram);
Initializer.initialize(inputConfiguration, inputProgram);
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down Expand Up @@ -138,7 +138,11 @@ public List<CtMethod<?>> getAmplifiedTestCases() {

@Override
public Minimizer getMinimizer() {
return new GeneralMinimizer();
return new ChangeMinimizer(this.currentClassTestToBeAmplified,
this.configuration, this.program,
this.pathToChangedVersionOfProgram,
this.failurePerAmplifiedTest
);
}

protected void reset() {
Expand Down
131 changes: 131 additions & 0 deletions dspot/src/main/java/fr/inria/stamp/minimization/ChangeMinimizer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package fr.inria.stamp.minimization;

import edu.emory.mathcs.backport.java.util.Collections;
import fr.inria.diversify.automaticbuilder.AutomaticBuilderFactory;
import fr.inria.diversify.dspot.support.DSpotCompiler;
import fr.inria.diversify.utils.AmplificationChecker;
import fr.inria.diversify.utils.AmplificationHelper;
import fr.inria.diversify.utils.DSpotUtils;
import fr.inria.diversify.utils.sosiefier.InputConfiguration;
import fr.inria.diversify.utils.sosiefier.InputProgram;
import fr.inria.stamp.test.launcher.TestLauncher;
import org.junit.runner.notification.Failure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
import spoon.reflect.visitor.filter.TypeFilter;

import java.io.File;
import java.util.List;
import java.util.Map;

/**
* Created by Benjamin DANGLOT
* benjamin.danglot@inria.fr
* on 07/03/18
*/
public class ChangeMinimizer extends GeneralMinimizer {

private static final Logger LOGGER = LoggerFactory.getLogger(ChangeMinimizer.class);

private CtType<?> testClass;

private InputConfiguration configuration;

private InputProgram program;

private String pathToChangedVersionOfProgram;

private Map<CtMethod<?>, Failure> failurePerAmplifiedTest;

private String classpath;

public ChangeMinimizer(CtType<?> testClass,
InputConfiguration configuration,
InputProgram program,
String pathToChangedVersionOfProgram,
Map<CtMethod<?>, Failure> failurePerAmplifiedTest) {
this.testClass = testClass;
this.configuration = configuration;
this.program = program;
this.pathToChangedVersionOfProgram = pathToChangedVersionOfProgram;
this.failurePerAmplifiedTest = failurePerAmplifiedTest;
this.classpath = AutomaticBuilderFactory
.getAutomaticBuilder(this.configuration)
.buildClasspath(this.program.getProgramDir())
+ AmplificationHelper.PATH_SEPARATOR + "target/dspot/dependencies/";
}

@Override
public CtMethod<?> minimize(CtMethod<?> amplifiedTestToBeMinimized) {
final CtMethod<?> generalMinimize = super.minimize(amplifiedTestToBeMinimized);
final CtMethod<?> changeMinimize = generalMinimize.clone();
final long time = System.currentTimeMillis();
final Failure failureToKeep = this.failurePerAmplifiedTest.get(amplifiedTestToBeMinimized);
changeMinimize.getElements(new TypeFilter<CtInvocation>(CtInvocation.class) {
@Override
public boolean matches(CtInvocation element) {
return AmplificationChecker.isAssert(element);
}
}).forEach(invocation ->
tryToRemoveAssertion(changeMinimize,
invocation,
failureToKeep
)
);
LOGGER.info("Reduce {}, {} statements to {} statements in {} ms.",
amplifiedTestToBeMinimized.getSimpleName(),
generalMinimize.getBody().getStatements().size(),
changeMinimize .getBody().getStatements().size(),
System.currentTimeMillis() - time
);
return changeMinimize;
}

private void tryToRemoveAssertion(CtMethod<?> amplifiedTestToBeMinimized,
CtInvocation<?> invocation,
Failure failureToKeep) {
final CtMethod<?> clone = amplifiedTestToBeMinimized.clone();
clone.getBody().removeStatement(invocation);
if (checkIfMinimizationIsOk(clone, failureToKeep)) {
amplifiedTestToBeMinimized.getBody().removeStatement(invocation);
}
}

private boolean checkIfMinimizationIsOk(CtMethod<?> amplifiedTestToBeMinimized, Failure failure) {
CtType<?> clone = this.testClass.clone();
// must compile
if (!printAndCompile(clone, amplifiedTestToBeMinimized)) {
return false;
}
// must have (the same?) failure
final List<Failure> failingTests = TestLauncher.run(this.configuration,
classpath +
AmplificationHelper.PATH_SEPARATOR +
this.pathToChangedVersionOfProgram + "/" + this.program.getClassesDir() +
AmplificationHelper.PATH_SEPARATOR +
this.pathToChangedVersionOfProgram + "/" + this.program.getTestClassesDir(),
clone,
Collections.singletonList(amplifiedTestToBeMinimized.getSimpleName()))
.getFailingTests();
return !failingTests.isEmpty();// && failingTests.get(0).equals(failure);
}

private boolean printAndCompile(CtType<?> clone, CtMethod<?> amplifiedTestToBeMinimized) {
clone.setParent(this.testClass.getParent());
this.testClass.getMethods().stream()
.filter(AmplificationChecker::isTest)
.forEach(clone::removeMethod);
clone.addMethod(amplifiedTestToBeMinimized);
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.pathToTmpTestSources));
return DSpotCompiler.compile(DSpotCompiler.pathToTmpTestSources,
classpath
+ AmplificationHelper.PATH_SEPARATOR +
this.program.getProgramDir() + "/" + this.program.getClassesDir()
+ AmplificationHelper.PATH_SEPARATOR +
this.program.getProgramDir() + "/" + this.program.getTestClassesDir(),
new File(this.pathToChangedVersionOfProgram + "/" + this.program.getTestClassesDir()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@ public boolean matches(CtVariableRead element) {
.filter(localVariable ->
variableReads.stream()
.map(CtVariableRead::getVariable)
.filter(variableRead ->
variableRead.equals(localVariable.getReference())
).count() == 1
.filter(variableRead -> variableRead.equals(localVariable.getReference()))
.count() == 1
).map(localVariable -> {
variableReads.stream()
.filter(variableRead ->
Expand All @@ -63,6 +62,7 @@ public boolean matches(CtVariableRead element) {
.replace(localVariable.getAssignment().clone());
return localVariable;
}).forEach(amplifiedTestToBeMinimized.getBody()::removeStatement);
//TODO we can inline all local variables that are used only in assertion
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public interface Minimizer {
/**
* this method aims to remove all useless statement according to a given test criterion
* @param amplifiedTestToBeMinimized
* @return
* @return a minimized version of amplifiedTestToBeMinimized
*/
CtMethod<?> minimize(CtMethod<?> amplifiedTestToBeMinimized);

Expand Down
3 changes: 1 addition & 2 deletions dspot/src/test/java/fr/inria/diversify/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@ public static AutomaticBuilder getBuilder() {
return builder;
}

@Deprecated
public static void reset() {

currentInputConfigurationLoaded = null;
}

public static void init(String pathToConfFile) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,13 @@ public class MavenAutomaticBuilderTest {

@Before
public void setUp() throws Exception {
Utils.reset();
Main.verbose = true;
MavenPitCommandAndOptions.evosuiteMode = false;
MavenPitCommandAndOptions.descartesMode = false;
}

@After
public void tearDown() throws Exception {
Utils.reset();
Main.verbose = false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,4 @@ public void setUp() throws Exception {
AmplificationHelper.setSeedRandom(72L);
ValueCreator.count = 0;
}

@After
public void tearDown() throws Exception {
Utils.reset();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public abstract class MavenAbstractTest {

@Before
public void setUp() throws Exception {
Utils.reset();
try {
FileUtils.forceDelete(new File("target/dspot/"));
} catch (Exception ignored) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package fr.inria.diversify.dspot;

import fr.inria.diversify.Utils;
import fr.inria.diversify.dspot.amplifier.TestDataMutator;
import fr.inria.diversify.dspot.selector.JacocoCoverageSelector;
import fr.inria.diversify.utils.sosiefier.InputConfiguration;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

Expand Down Expand Up @@ -34,11 +32,6 @@ public void setUp() throws Exception {
}
}

@After
public void tearDown() throws Exception {
Utils.reset();
}

@Test
public void test() throws Exception {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ public void setUp() throws Exception {
super.setUp();
}

@Override
@After
public void tearDown() throws Exception {
super.tearDown();
Main.verbose = false;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package fr.inria.diversify.dspot.inheritance;

import fr.inria.diversify.Utils;
import fr.inria.diversify.dspot.DSpot;
import fr.inria.diversify.dspot.amplifier.TestDataMutator;
import fr.inria.diversify.dspot.selector.JacocoCoverageSelector;
import fr.inria.diversify.utils.sosiefier.InputConfiguration;
import org.junit.Before;
import org.junit.Test;
import spoon.reflect.declaration.CtType;

Expand All @@ -21,11 +19,6 @@
*/
public class InheritanceTest {

@Before
public void setUp() throws Exception {
Utils.reset();
}

@Test
public void testInheritanceMethod() throws Exception {
final InputConfiguration configuration = new InputConfiguration("src/test/resources/sample/sample.properties");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Collectors;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public void test() throws Exception {
This selector aims at keeping amplified test that execute new lines in the source code.
*/

Utils.reset();
Utils.init("src/test/resources/test-projects/test-projects.properties");
EntryPoint.verbose = true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public class ExecutedMutantSelectorTest {

@Before
public void setUp() throws Exception {
Utils.reset();
Utils.init("src/test/resources/test-projects/test-projects.properties");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public void testPit() throws Exception {
Run the PitRunner on the test-project example.
Checks that the PitRunner return well the results, and verify state of mutant.
*/
Utils.reset();
AmplificationHelper.setSeedRandom(23L);
MavenPitCommandAndOptions.descartesMode = false;
MavenPitCommandAndOptions.evosuiteMode = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,8 @@
*/
public class TestJacocoExecutor {

@Before
public void setUp() throws Exception {
Utils.reset();
}

@After
public void tearDown() throws Exception {
Utils.reset();
}

@Test
public void testJacocoExecutorOnJMockit() throws Exception {
Utils.reset();
Utils.init("src/test/resources/jmockit/mock.properties");

final CtClass<?> jmockitTest = Utils.findClass("org.baeldung.mocks.jmockit.LoginControllerIntegrationTest");
Expand All @@ -43,7 +32,6 @@ public void testJacocoExecutorOnJMockit() throws Exception {

@Test
public void testJacocoExecutorOnEasyMock() throws Exception {
Utils.reset();
Utils.init("src/test/resources/easymock/mock.properties");

final CtClass<?> easyMockTest = Utils.findClass("org.baeldung.mocks.easymock.LoginControllerIntegrationTest");
Expand All @@ -57,7 +45,6 @@ public void testJacocoExecutorOnEasyMock() throws Exception {

@Test
public void testJacocoExecutor() throws Exception {
Utils.reset();
Utils.init("src/test/resources/test-projects/test-projects.properties");
final CtClass<?> testClass = Utils.findClass("example.TestSuiteExample");
JacocoExecutor jacocoExecutor = new JacocoExecutor(Utils.getInputProgram(), Utils.getInputConfiguration(), testClass);
Expand All @@ -73,7 +60,6 @@ public void testJacocoExecutor() throws Exception {
@Test
@Ignore
public void testJacocoExecutorOnMockito() throws Exception {
Utils.reset();
Utils.init("src/test/resources/mockito/mockito.properties");
final CtClass<?> testClass = Utils.findClass("info.sanaulla.dal.BookDALTest");
JacocoExecutor jacocoExecutor = new JacocoExecutor(Utils.getInputProgram(), Utils.getInputConfiguration(), testClass);
Expand All @@ -89,7 +75,6 @@ public void testJacocoExecutorOnMockito() throws Exception {
@Test
@Ignore
public void testJacocoExecutorOnMockito2() throws Exception {
Utils.reset();
Utils.init("src/test/resources/mockito2/mock.properties");

final CtClass<?> mockitoTest = Utils.findClass("org.baeldung.mocks.mockito.LoginControllerIntegrationTest");
Expand Down
Loading

0 comments on commit ddf3c97

Please sign in to comment.