use of spoon.SpoonException in project repairnator by Spirals-Team.
the class NopolRepair method businessExecute.
@Override
protected void businessExecute() {
this.getLogger().debug("Start to use nopol to repair...");
this.setPipelineState(PipelineState.NOPOL_NOTPATCHED);
Metrics metric = this.inspector.getJobStatus().getMetrics();
List<URL> classPath = this.inspector.getJobStatus().getRepairClassPath();
File[] sources = this.inspector.getJobStatus().getRepairSourceDir();
if (classPath != null && sources != null) {
String[] sourcesStr = new String[sources.length];
int i = 0;
for (File f : sources) {
sourcesStr[i++] = f.getAbsolutePath();
}
List<FailureLocation> failureLocationList = new ArrayList<>(this.inspector.getJobStatus().getFailureLocations());
Collections.sort(failureLocationList, new ComparatorFailureLocation());
boolean patchCreated = false;
int passingTime = 0;
for (FailureLocation failureLocation : failureLocationList) {
Set<String> erroringTests = failureLocation.getErroringMethods();
Set<String> failingTests = failureLocation.getFailingMethods();
// this one is used to loop on Nopol over tests to ignore. It can be a list containing an empty list.
List<List<String>> listOfTestToIgnore = new ArrayList<>();
boolean ignoreError = false;
// in that case: no tests to ignore
if (erroringTests.isEmpty() || failingTests.isEmpty()) {
listOfTestToIgnore.add(new ArrayList<>());
// then we will first try to ignore erroring tests, then to ignore failing tests
} else {
listOfTestToIgnore.add(new ArrayList<>(erroringTests));
listOfTestToIgnore.add(new ArrayList<>(failingTests));
ignoreError = true;
}
for (List<String> testsToIgnore : listOfTestToIgnore) {
NopolInformation nopolInformation;
if (testsToIgnore.isEmpty()) {
nopolInformation = new NopolInformation(failureLocation, IgnoreStatus.NOTHING_TO_IGNORE);
} else {
if (ignoreError) {
nopolInformation = new NopolInformation(failureLocation, IgnoreStatus.IGNORE_ERRORING);
ignoreError = false;
} else {
nopolInformation = new NopolInformation(failureLocation, IgnoreStatus.IGNORE_FAILING);
}
}
this.nopolInformations.add(nopolInformation);
nopolInformation.setStatus(NopolStatus.RUNNING);
String testClass = failureLocation.getClassName();
int timeout = (TOTAL_MAX_TIME - passingTime) / 2;
if (timeout < MIN_TIMEOUT) {
timeout = MIN_TIMEOUT;
}
nopolInformation.setAllocatedTime(timeout);
this.getLogger().debug("Launching repair with Nopol for following test class: " + testClass + " (should timeout in " + timeout + " minutes)");
NopolContext nopolContext = new NopolContext(sources, classPath.toArray(new URL[classPath.size()]), new String[] { testClass }, testsToIgnore);
nopolContext.setComplianceLevel(8);
nopolContext.setTimeoutTestExecution(300);
nopolContext.setMaxTimeEachTypeOfFixInMinutes(15);
nopolContext.setMaxTimeInMinutes(timeout);
nopolContext.setLocalizer(NopolContext.NopolLocalizer.COCOSPOON);
nopolContext.setSolverPath(this.getConfig().getZ3solverPath());
nopolContext.setSynthesis(NopolContext.NopolSynthesis.DYNAMOTH);
nopolContext.setType(RepairType.COND_THEN_PRE);
nopolContext.setOnlyOneSynthesisResult(false);
nopolContext.setOutputFolder(this.getInspector().getRepoLocalPath());
nopolInformation.setNopolContext(nopolContext);
SolverFactory.setSolver(nopolContext.getSolver(), nopolContext.getSolverPath());
long beforeNopol = new Date().getTime();
try {
final NoPol nopol = new NoPol(nopolContext);
Factory spoonFactory = nopol.getSpooner().spoonFactory();
List<PatchAndDiff> patchAndDiffs = new ArrayList<>();
final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future<NopolResult> nopolExecution = executor.submit(new Callable<NopolResult>() {
@Override
public NopolResult call() throws Exception {
NopolResult result = null;
try {
result = nopol.build();
} catch (RuntimeException e) {
addStepError("Got runtime exception while running Nopol", e);
}
return result;
}
});
try {
executor.shutdown();
NopolResult result = nopolExecution.get(nopolContext.getMaxTimeInMinutes(), TimeUnit.MINUTES);
if (result == null) {
result = nopol.getNopolResult();
}
nopolInformation.setNbStatements(result.getNbStatements());
nopolInformation.setNbAngelicValues(result.getNbAngelicValues());
String failureLocationWithoutDots = failureLocation.getClassName().replace('.', '/');
metric.addAngelicValueByTest(failureLocationWithoutDots, result.getNbAngelicValues());
List<Patch> patches = result.getPatches();
if (patches != null && !patches.isEmpty()) {
for (Patch patch : patches) {
String diff = patch.toDiff(spoonFactory, nopolContext);
patchAndDiffs.add(new PatchAndDiff(patch, diff));
}
nopolInformation.setPatches(patchAndDiffs);
nopolInformation.setStatus(NopolStatus.PATCH);
patchCreated = true;
} else {
nopolInformation.setStatus(NopolStatus.NOPATCH);
}
} catch (TimeoutException exception) {
this.addStepError("Timeout: execution time > " + nopolContext.getMaxTimeInMinutes() + " " + TimeUnit.MINUTES);
nopolExecution.cancel(true);
executor.shutdownNow();
nopolInformation.setStatus(NopolStatus.TIMEOUT);
NopolResult result = nopol.getNopolResult();
nopolInformation.setNbStatements(result.getNbStatements());
nopolInformation.setNbAngelicValues(result.getNbAngelicValues());
} catch (InterruptedException | ExecutionException e) {
this.addStepError(e.getMessage());
nopolExecution.cancel(true);
executor.shutdownNow();
nopolInformation.setStatus(NopolStatus.EXCEPTION);
nopolInformation.setExceptionDetail(e.getMessage());
NopolResult result = nopol.getNopolResult();
nopolInformation.setNbStatements(result.getNbStatements());
nopolInformation.setNbAngelicValues(result.getNbAngelicValues());
}
} catch (SpoonException e) {
this.addStepError(e.getMessage());
nopolInformation.setStatus(NopolStatus.EXCEPTION);
nopolInformation.setExceptionDetail(e.getMessage());
}
long afterNopol = new Date().getTime();
nopolInformation.setDateEnd();
int localPassingTime = Math.round((afterNopol - beforeNopol) / 60000);
nopolInformation.setPassingTime(localPassingTime);
passingTime += localPassingTime;
}
}
File nopolLog = new File(System.getProperty("user.dir"), "debug.log");
if (nopolLog.exists()) {
String nopolDestName = "repairnator.nopol.log";
File nopolDest = new File(this.getInspector().getRepoLocalPath(), nopolDestName);
try {
Files.move(nopolLog.toPath(), nopolDest.toPath());
this.getInspector().getJobStatus().addFileToPush(nopolDestName);
} catch (IOException e) {
getLogger().error("Error while renaming nopol log", e);
}
}
File nopolProperties = new File(this.getInspector().getRepoLocalPath() + "/repairnator.nopol.results");
this.getInspector().getJobStatus().addFileToPush("repairnator.nopol.results");
File patchDir = new File(this.getInspector().getRepoLocalPath() + "/repairnatorPatches");
patchDir.mkdir();
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(nopolProperties));
int infoNumber = 0;
for (NopolInformation information : this.nopolInformations) {
String informationStr = "nopolinfo #" + (infoNumber++) + "\n" + "location: " + information.getLocation() + "\n" + "status: " + information.getStatus().name() + "\n" + "dateEnd: " + information.getDateEnd().toString() + "\n" + "allocatedtime: " + information.getAllocatedTime() + "minutes \n" + "passingTime: " + information.getPassingTime() + "minutes \n" + "nb patches: " + information.getPatches().size() + "\n" + "nopol context: " + information.getNopolContext() + "\n" + "exception: " + information.getExceptionDetail() + "\n" + "nbStatements: " + information.getNbStatements() + "\n" + "nbAngelicValues: " + information.getNbAngelicValues() + "\n" + "ignoreStatus: " + information.getIgnoreStatus().name() + "\n" + "----------\n\n";
writer.write(informationStr);
writer.newLine();
writer.newLine();
writer.flush();
int patchNumber = 0;
for (PatchAndDiff patchAndDiff : information.getPatches()) {
File patchFile = new File(patchDir.getPath() + "/" + information.getLocation().getClassName() + "_patch_" + (patchNumber++));
Patch patch = patchAndDiff.getPatch();
BufferedWriter patchWriter = new BufferedWriter(new FileWriter(patchFile));
String patchWrite = "location: " + patch.getSourceLocation() + "\n" + "type: " + patch.getType() + "\n" + "patch: " + patchAndDiff.getDiff();
patchWriter.write(patchWrite);
patchWriter.flush();
patchWriter.close();
}
}
writer.close();
} catch (IOException e) {
this.addStepError("Error while writing nopol informations");
this.getLogger().error("Error while writing nopol informations", e);
}
if (!patchCreated) {
this.addStepError("No patch has been generated by Nopol. Look at the trace to get more information.");
return;
}
this.setPipelineState(PipelineState.NOPOL_PATCHED);
this.getInspector().getJobStatus().setHasBeenPatched(true);
List<String> nopolPatches = new ArrayList<>();
for (NopolInformation information : this.nopolInformations) {
for (PatchAndDiff p : information.getPatches()) {
nopolPatches.add(p.getDiff());
}
}
this.getInspector().getJobStatus().setNopolPatches(nopolPatches);
} else {
this.addStepError("No classpath or sources directory has been given. Nopol can't be launched.");
}
}
use of spoon.SpoonException in project repairnator by Spirals-Team.
the class AstorRepair method businessExecute.
@Override
protected void businessExecute() {
this.getLogger().info("Start to repair using Astor");
JobStatus jobStatus = this.getInspector().getJobStatus();
List<String> astorPatches = new ArrayList<>();
List<URL> classPath = this.inspector.getJobStatus().getRepairClassPath();
File[] sources = this.inspector.getJobStatus().getRepairSourceDir();
if (classPath != null && sources != null) {
List<String> dependencies = new ArrayList<>();
for (URL url : jobStatus.getRepairClassPath()) {
if (url.getFile().endsWith(".jar")) {
dependencies.add(url.getPath());
}
}
final List<String> astorArgs = new ArrayList<>();
astorArgs.add("-dependencies");
astorArgs.add(StringUtils.join(dependencies, ":"));
astorArgs.add("-mode");
astorArgs.add("jgenprog");
astorArgs.add("-location");
astorArgs.add(jobStatus.getFailingModulePath());
String relativeSourcePath = new File(jobStatus.getFailingModulePath()).toURI().relativize(jobStatus.getRepairSourceDir()[0].toURI()).getPath();
astorArgs.add("-srcjavafolder");
astorArgs.add(relativeSourcePath);
astorArgs.add("-stopfirst");
astorArgs.add("true");
astorArgs.add("-population");
astorArgs.add("1");
// astorArgs.add("-loglevel");
// astorArgs.add("DEBUG");
astorArgs.add("-parameters");
astorArgs.add("timezone:Europe/Paris:maxnumbersolutions:3:limitbysuspicious:false:maxmodificationpoints:1000:javacompliancelevel:8:logfilepath:" + this.getInspector().getRepoLocalPath() + "/repairnator.astor.log");
astorArgs.add("-maxtime");
astorArgs.add(MAX_TIME_EXECUTION + "");
astorArgs.add("-seed");
astorArgs.add("1");
final AstorMain astorMain = new AstorMain();
final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future<AstorOutputStatus> astorExecution = executor.submit(new Callable<AstorOutputStatus>() {
@Override
public AstorOutputStatus call() throws Exception {
AstorOutputStatus status = null;
try {
astorMain.execute(astorArgs.toArray(new String[0]));
if (astorMain.getEngine() != null) {
status = astorMain.getEngine().getOutputStatus();
} else {
status = AstorOutputStatus.ERROR;
}
} catch (SpoonException e) {
status = AstorOutputStatus.ERROR;
addStepError("Got SpoonException while running Astor", e);
} catch (RuntimeException e) {
addStepError("Got runtime exception while running Astor", e);
status = AstorOutputStatus.ERROR;
}
return status;
}
});
AstorOutputStatus status = null;
try {
executor.shutdown();
status = astorExecution.get(MAX_TIME_EXECUTION, TimeUnit.MINUTES);
if (astorMain.getEngine() != null) {
List<ProgramVariant> solutions = astorMain.getEngine().getSolutions();
if (solutions != null) {
for (ProgramVariant pv : solutions) {
if (pv.isSolution()) {
astorPatches.add(pv.getPatchDiff());
}
}
}
}
} catch (Exception e) {
status = AstorOutputStatus.ERROR;
this.addStepError("Error while executing astor with args: " + StringUtils.join(astorArgs, ","), e);
}
jobStatus.addFileToPush("repairnator.astor.log");
jobStatus.setAstorPatches(astorPatches);
jobStatus.setAstorStatus(status);
String jsonpath;
try {
jsonpath = astorMain.getEngine().getProjectFacade().getProperties().getWorkingDirRoot() + File.separator + ConfigurationProperties.getProperty("jsonoutputname") + ".json";
} catch (NullPointerException e) {
jsonpath = null;
}
if (jsonpath != null) {
File jsonResultFile = new File(jsonpath);
if (jsonResultFile.exists()) {
try {
FileUtils.copyFile(jsonResultFile, new File(this.getInspector().getRepoLocalPath() + "/repairnator.astor.results.json"));
} catch (IOException e) {
this.addStepError("Error while moving astor JSON results", e);
}
JsonParser jsonParser = new JsonParser();
try {
JsonElement root = jsonParser.parse(new FileReader(jsonResultFile));
this.getInspector().getJobStatus().setAstorResults(root);
} catch (FileNotFoundException e) {
this.addStepError("Error while reading astor JSON results", e);
}
jobStatus.addFileToPush("repairnator.astor.results.json");
}
}
if (astorPatches.isEmpty()) {
this.setPipelineState(PipelineState.ASTOR_NOTPATCHED);
} else {
this.setPipelineState(PipelineState.ASTOR_PATCHED);
this.getInspector().getJobStatus().setHasBeenPatched(true);
}
}
}
use of spoon.SpoonException in project spoon by INRIA.
the class CtRenameLocalVariableRefactoring method detectNameConflicts.
@Override
protected void detectNameConflicts() {
/*
* There can be these conflicts
* 1) target variable would shadow before declared variable (parameter, localVariable, catchVariable)
* --------------------------------------------------------------------------------------------------
*/
PotentialVariableDeclarationFunction potentialDeclarationFnc = new PotentialVariableDeclarationFunction(newName);
CtVariable<?> var = getTarget().map(potentialDeclarationFnc).first();
if (var != null) {
if (var instanceof CtField) {
/*
* we have found a field of same name.
* It is not problem, because variables can hide field declaration.
* Do nothing - OK
*/
} else if (potentialDeclarationFnc.isTypeOnTheWay()) {
/*
* There is a local class declaration between future variable reference and variable declaration `var`.
* The found variable declaration `var` can be hidden by target variable with newName
* as long as there is no reference to `var` in visibility scope of the target variable.
* So search for such `var` reference now
*/
CtVariableReference<?> shadowedVar = target.map(new SiblingsFunction().includingSelf(true).mode(Mode.NEXT)).map(new VariableReferenceFunction(var)).first();
if (shadowedVar != null) {
// found variable reference, which would be shadowed by variable after rename.
createNameConflictIssue(var, shadowedVar);
} else {
/*
* there is no local variable reference, which would be shadowed by variable after rename.
* OK
*/
}
} else {
/*
* the found variable is in conflict with target variable with newName
*/
createNameConflictIssue(var);
}
}
/*
* 2) target variable is shadowed by later declared variable
* ---------------------------------------------------------
*/
final QueryDriver queryDriver = new QueryDriver();
getTarget().map(new LocalVariableScopeFunction(queryDriver)).select(new Filter<CtElement>() {
/**
* return true for all CtVariables, which are in conflict
*/
@Override
public boolean matches(CtElement element) {
if (element instanceof CtType<?>) {
CtType<?> localClass = (CtType<?>) element;
// TODO use faster hasField, implemented using map(new AllFieldsFunction()).select(new NameFilter(newName)).first()!=null
Collection<CtFieldReference<?>> fields = localClass.getAllFields();
for (CtFieldReference<?> fieldRef : fields) {
if (newName.equals(fieldRef.getSimpleName())) {
/*
* we have found a local class field, which will shadow input local variable if it's reference is in visibility scope of that field.
* Search for target variable reference in visibility scope of this field.
* If found than we cannot rename target variable to newName, because that reference would be shadowed
*/
queryDriver.ignoreChildrenOf(element);
CtLocalVariableReference<?> shadowedVar = element.map(new LocalVariableReferenceFunction(target)).first();
if (shadowedVar != null) {
createNameConflictIssue(fieldRef.getFieldDeclaration(), shadowedVar);
return true;
}
return false;
}
}
return false;
}
if (element instanceof CtVariable<?>) {
CtVariable<?> variable = (CtVariable<?>) element;
if (newName.equals(variable.getSimpleName()) == false) {
// the variable with different name. Ignore it
return false;
}
// we have found a variable with new name
if (variable instanceof CtField) {
throw new SpoonException("This should not happen. The children of local class which contains a field with new name should be skipped!");
}
if (variable instanceof CtCatchVariable || variable instanceof CtLocalVariable || variable instanceof CtParameter) {
/*
* we have found a catch variable or local variable or parameter with new name.
*/
if (queryDriver.isInContextOfLocalClass()) {
/*
* We are in context of local class.
* This variable would shadow input local variable after rename
* so we cannot rename if there exist a local variable reference in variable visibility scope.
*/
queryDriver.ignoreChildrenOf(variable.getParent());
CtQueryable searchScope;
if (variable instanceof CtLocalVariable) {
searchScope = variable.map(new SiblingsFunction().includingSelf(true).mode(Mode.NEXT));
} else {
searchScope = variable.getParent();
}
CtLocalVariableReference<?> shadowedVar = searchScope.map(new LocalVariableReferenceFunction(target)).first();
if (shadowedVar != null) {
// found local variable reference, which would be shadowed by variable after rename.
createNameConflictIssue(variable, shadowedVar);
return true;
}
// there is no local variable reference, which would be shadowed by variable after rename.
return false;
} else {
/*
* We are not in context of local class.
* So this variable is in conflict. Return it
*/
createNameConflictIssue(variable);
return true;
}
} else {
// Any new variable type???
throw new SpoonException("Unexpected variable " + variable.getClass().getName());
}
}
return false;
}
}).first();
}
use of spoon.SpoonException in project spoon by INRIA.
the class Refactoring method copyMethod.
/**
* See doc in {@link CtMethod#copyMethod()}
*/
public static CtMethod<?> copyMethod(final CtMethod<?> method) {
CtMethod<?> clone = method.clone();
String tentativeTypeName = method.getSimpleName() + "Copy";
CtType parent = method.getParent(CtType.class);
while (parent.getMethodsByName(tentativeTypeName).size() > 0) {
tentativeTypeName += "X";
}
final String cloneMethodName = tentativeTypeName;
clone.setSimpleName(cloneMethodName);
parent.addMethod(clone);
new CtScanner() {
@Override
public <T> void visitCtExecutableReference(CtExecutableReference<T> reference) {
CtExecutable<T> declaration = reference.getDeclaration();
if (declaration == null) {
return;
}
if (declaration == method) {
reference.setSimpleName(cloneMethodName);
}
if (reference.getDeclaration() != clone) {
throw new SpoonException("post condition broken " + reference);
}
super.visitCtExecutableReference(reference);
}
}.scan(clone);
return clone;
}
use of spoon.SpoonException in project spoon by INRIA.
the class ReplaceParametrizedTest method testContract.
@Test
public void testContract() throws Throwable {
List<String> problems = new ArrayList<>();
// contract: all elements are replaceable wherever they are in the model
// this test puts them at all possible locations
CtType<?> toTest = typeToTest.getModelInterface();
CtElement o = factory.Core().create((Class<? extends CtElement>) toTest.getActualClass());
for (MetamodelProperty mmField : typeToTest.getRoleToProperty().values()) {
Class<?> argType = mmField.getItemValueType().getActualClass();
if (!CtElement.class.isAssignableFrom(argType)) {
continue;
}
CtTypeReference<?> itemType = mmField.getItemValueType();
// special cases...
if (itemType.getQualifiedName().equals(CtStatement.class.getName())) {
// the children of CtLoop wraps CtStatement into an implicit CtBlock. So make a block directly to test plain get/set and not wrapping.
itemType = factory.createCtTypeReference(CtBlock.class);
}
if (o.getClass().getSimpleName().equals("CtAnnotationFieldAccessImpl") && mmField.getRole() == CtRole.VARIABLE) {
itemType = factory.createCtTypeReference(CtFieldReference.class);
} else if (CtFieldAccess.class.isAssignableFrom(o.getClass()) && mmField.getRole() == CtRole.VARIABLE) {
itemType = factory.createCtTypeReference(CtFieldReference.class);
}
CtElement argument = (CtElement) createCompatibleObject(itemType);
assertNotNull(argument);
// we create a fresh object
CtElement receiver = ((CtElement) o).clone();
RoleHandler rh = RoleHandlerHelper.getRoleHandler(o.getClass(), mmField.getRole());
if (mmField.isUnsettable()) {
try {
// we invoke the setter
invokeSetter(rh, receiver, argument);
} catch (SpoonException e) {
// ok this unsettable property has no setter at all
return;
}
// this unsettable property has setter, but it should do nothing
CtRole argumentsRoleInParent = argument.getRoleInParent();
if (argumentsRoleInParent == null) {
// OK - unsettable property set no value
continue;
}
if (argumentsRoleInParent == mmField.getRole()) {
problems.add("UnsettableProperty " + mmField + " sets the value");
} else {
if (mmField.isDerived()) {
// it is OK, that setting of value into derived unsettable field influences other field
// Example 1: CtCatchVariable.setType(x) influences result of getMultitype()
// Example 2: CtEnumValue.setAssignment(x) influences result of getDefaultExpression()
} else {
problems.add("UnsettableProperty " + mmField + " sets the value into different role " + argumentsRoleInParent);
}
}
continue;
}
// we invoke the setter
invokeSetter(rh, receiver, argument);
// contract: a property setter sets properties that are visitable by a scanner
CtElement finalArgument = argument;
class Scanner extends CtScanner {
boolean found = false;
@Override
public void scan(CtRole role, CtElement e) {
super.scan(role, e);
if (e == finalArgument) {
if (rh.getRole() == role || rh.getRole().getSuperRole() == role) {
found = true;
return;
}
// if (rh.getRole()==CtRole.TYPE && role==CtRole.MULTI_TYPE) {
// //CtCatchVaraible#type sets CtCatchVaraible#multiType - OK
// found = true;
// return;
// }
problems.add("Argument was set into " + rh.getRole() + " but was found in " + role);
}
}
}
;
Scanner s = new Scanner();
receiver.accept(s);
assertTrue("Settable field " + mmField.toString() + " should set value.\n" + getReport(problems), s.found);
// contract: a property getter on the same role can be used to get the value back
assertSame(argument, invokeGetter(rh, receiver));
final CtElement argument2 = argument.clone();
assertNotSame(argument, argument2);
// we do the replace
argument.replace(argument2);
// the new element is indeed now in this AST
assertTrue(receiver.getClass().getSimpleName() + " failed for " + mmField, receiver.getElements(new Filter<CtElement>() {
@Override
public boolean matches(CtElement element) {
return element == argument2;
}
}).size() == 1);
}
if (problems.size() > 0) {
fail(getReport(problems));
}
}
Aggregations