Search in sources :

Example 1 with NoPol

use of fr.inria.lille.repair.nopol.NoPol 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.");
    }
}
Also used : NopolContext(fr.inria.lille.repair.common.config.NopolContext) FileWriter(java.io.FileWriter) Factory(spoon.reflect.factory.Factory) SolverFactory(fr.inria.lille.commons.synthesis.smt.solver.SolverFactory) URL(java.net.URL) BufferedWriter(java.io.BufferedWriter) ComparatorFailureLocation(fr.inria.spirals.repairnator.process.testinformation.ComparatorFailureLocation) Metrics(fr.inria.spirals.repairnator.process.inspectors.Metrics) NoPol(fr.inria.lille.repair.nopol.NoPol) PatchAndDiff(fr.inria.spirals.repairnator.process.nopol.PatchAndDiff) NopolInformation(fr.inria.spirals.repairnator.process.nopol.NopolInformation) ComparatorFailureLocation(fr.inria.spirals.repairnator.process.testinformation.ComparatorFailureLocation) FailureLocation(fr.inria.spirals.repairnator.process.testinformation.FailureLocation) NopolResult(fr.inria.lille.repair.nopol.NopolResult) SpoonException(spoon.SpoonException) IOException(java.io.IOException) SpoonException(spoon.SpoonException) IOException(java.io.IOException) File(java.io.File) Patch(fr.inria.lille.repair.common.patch.Patch)

Aggregations

SolverFactory (fr.inria.lille.commons.synthesis.smt.solver.SolverFactory)1 NopolContext (fr.inria.lille.repair.common.config.NopolContext)1 Patch (fr.inria.lille.repair.common.patch.Patch)1 NoPol (fr.inria.lille.repair.nopol.NoPol)1 NopolResult (fr.inria.lille.repair.nopol.NopolResult)1 Metrics (fr.inria.spirals.repairnator.process.inspectors.Metrics)1 NopolInformation (fr.inria.spirals.repairnator.process.nopol.NopolInformation)1 PatchAndDiff (fr.inria.spirals.repairnator.process.nopol.PatchAndDiff)1 ComparatorFailureLocation (fr.inria.spirals.repairnator.process.testinformation.ComparatorFailureLocation)1 FailureLocation (fr.inria.spirals.repairnator.process.testinformation.FailureLocation)1 BufferedWriter (java.io.BufferedWriter)1 File (java.io.File)1 FileWriter (java.io.FileWriter)1 IOException (java.io.IOException)1 URL (java.net.URL)1 SpoonException (spoon.SpoonException)1 Factory (spoon.reflect.factory.Factory)1