/** * Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite * contributors * * This file is part of EvoSuite. * * EvoSuite is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3.0 of the License, or * (at your option) any later version. * * EvoSuite is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>. */ package org.evosuite.intellij.util; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import org.evosuite.intellij.EvoParameters; import org.jetbrains.annotations.NotNull; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; /** * Created by Andrea Arcuri on 28/11/15. */ public class ProcessRunner { public static Process execute(Project project, AsyncGUINotifier notifier, EvoParameters params, File dir, Set<String> classes, int managerPort) { List<String> list; if(params.usesMaven()){ list = getMavenCommand(params, classes,managerPort); } else { list = getEvoJarCommand(project, dir,params, classes,managerPort); } String[] command = list.toArray(new String[list.size()]); String concat = "Going to execute command:\n"; for(String c : command){ concat += c + " "; } concat += "\nin folder: "+dir.getAbsolutePath(); concat += "\n"; System.out.println(concat); notifier.printOnConsole(concat);//FIXME: done here it gets cleared by IntelliJ... really fucking annoying try { ProcessBuilder builder = new ProcessBuilder(); builder.directory(dir); builder.command(command); Map<String,String> map = builder.environment(); map.put("JAVA_HOME", params.getJavaHome()); Process p = builder.start(); notifier.attachProcess(p); notifier.printOnConsole(concat); //this doesn't work either... return p; } catch (IOException e) { notifier.failed("Failed to execute EvoSuite: "+e.getMessage()); return null; } } private static List<String> getEvoJarCommand( Project project, File dir, EvoParameters params, Set<String> classes, int port) throws IllegalArgumentException{ List<String> list = new ArrayList<>(); String java = "java"; if(Utils.isWindows()){ java += ".exe"; } list.add(params.getJavaHome() + File.separator + "bin" + File.separator + java); list.add("-jar"); list.add(params.getEvosuiteJarLocation()); list.add("-continuous"); list.add("execute"); //No need to specify target, as we do specify the CUT list //list.add("-target"); //list.add(target); if(classes==null || classes.isEmpty()){ //if we want to change it, we need to handle 'target' throw new IllegalArgumentException("Need to specify class list"); } list.add("-Dspawn_process_manager_port="+port); //the memory is per core list.add("-Dctg_memory="+ (params.getMemory() * params.getCores())); list.add("-Dctg_cores="+params.getCores()); list.add("-Dctg_time_per_class=" + params.getTime()); list.add("-Dctg_export_folder=" + params.getFolder()); if(classes != null && classes.size() >= 0) { if (classes.size() <= 10) { String cuts = getCommaList(classes); list.add("-Dctg_selected_cuts=" + cuts); } else { String filePath = writeClassesToFile(classes); list.add("-Dctg_selected_cuts_file_location="+filePath); } } if(dir==null || !dir.exists()){ throw new IllegalArgumentException("Invalid module dir"); } String folderPath = dir.getAbsolutePath(); Module module = null; for(Module m : ModuleManager.getInstance(project).getModules()){ String modulePath = Utils.getFolderLocation(m); if(folderPath.equals(modulePath)){ module = m; break; } } if(module == null){ throw new IllegalArgumentException("Cannot determine module for "+folderPath); } String cp = Utils.getFullClassPath(module); String path = writeLineToFile("EvoSuite_ctg_classpath_file", cp); list.add("-DCP_file_path="+path); //list.add("-DCP=" + cp);//this did not work properly on Windows return list; } private static String writeClassesToFile(Set<String> classes) { return writeLineToFile("EvoSuite_ctg_CUT_file", getCommaList(classes)); } private static String writeLineToFile(String fileName, String line) { try { File file = File.createTempFile(fileName,".txt"); file.deleteOnExit(); BufferedWriter out = new BufferedWriter(new FileWriter(file)); out.write(line); out.newLine(); out.close(); return file.getAbsolutePath(); } catch (Exception e) { throw new IllegalStateException("Failed to create tmp file: "+e.getMessage()); } } @NotNull private static List<String> getMavenCommand(EvoParameters params, Set<String> classes, int port) { List<String> list = new ArrayList<>(); list.add(params.getMvnLocation()); list.add("compile"); list.add("evosuite:generate"); list.add("-Dcores=" + params.getCores()); //the memory is per core list.add("-DmemoryInMB=" + (params.getMemory() * params.getCores())); list.add("-DtimeInMinutesPerClass=" + params.getTime()); list.add("-DspawnManagerPort="+port); if(classes != null && classes.size() >= 0) { if (classes.size() <= 10) { String cuts = getCommaList(classes); list.add("-Dcuts=" + cuts); } else { String filePath = writeClassesToFile(classes); list.add("-DcutsFile="+filePath); } } list.add("evosuite:export"); //note, here -Dctg_export_folder would do as well list.add("-DtargetFolder=" + params.getFolder()); return list; } private static String getCommaList(Set<String> set){ if (set != null && !set.isEmpty()) { return String.join(",", set); } return null; } }