Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Windows-compatibility #362

Merged
merged 4 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.inria.sacha.automaticRepair</groupId>
<artifactId>astor</artifactId>
Expand Down Expand Up @@ -170,13 +170,13 @@
<repository>
<id>EvoSuite</id>
<name>EvoSuite Repository</name>
<url>http://www.evosuite.org/m2</url>
<url>https://www.evosuite.org/m2</url>
</repository>

<repository>
<id>sachaproject.gforge.inria.fr-release</id>
<name>Maven Repository for Spoon Release</name>
<url>http://sachaproject.gforge.inria.fr/repositories/releases/</url>
<url>https://sachaproject.gforge.inria.fr/repositories/releases/</url>
<snapshots />
</repository>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,12 @@ public TestCaseVariantValidationResult runTestFromEvoSuite(ProgramVariant curren
// Set up dirs
String classpathForCompile = "";
classpathForCompile = projectFacade.getProperties().getDependenciesString() + File.pathSeparator
+ projectFacade.getOutDirWithPrefix(currentVariant.currentMutatorIdentifier()) + File.pathSeparator//
+ new File(projectFacade.getOutDirWithPrefix(currentVariant.currentMutatorIdentifier()))
.getAbsolutePath()
+ File.pathSeparator//
+ new File(ConfigurationProperties.getProperty("evosuitejar")).getAbsolutePath() + File.pathSeparator
+ projectFacade.getOutDirWithPrefix(currentVariant.DEFAULT_ORIGINAL_VARIANT);
+ new File(projectFacade.getOutDirWithPrefix(currentVariant.DEFAULT_ORIGINAL_VARIANT))
.getAbsolutePath();

String outPutTest = projectFacade.getOutDirWithPrefix("/evosuite/evosuite-tests/" + sufix);

Expand Down Expand Up @@ -129,8 +132,8 @@ public TestCaseVariantValidationResult runTestFromEvoSuite(ProgramVariant curren
List<String> pathTestGenerated = new ArrayList<String>();

log.debug("Generating test for the first time");
boolean executed = fev.runEvosuite(currentVariant, classesToGenerateTests, projectFacade, testEScodepath,
runOverOriginal);
boolean executed = fev.runEvosuite(currentVariant, classesToGenerateTests, projectFacade,
esPath.getAbsolutePath(), runOverOriginal);

// we collect the files generated

Expand All @@ -145,7 +148,7 @@ public TestCaseVariantValidationResult runTestFromEvoSuite(ProgramVariant curren
// Collect test generated from files generated by ES
for (String f : pathTestGenerated) {
String qualifiedTestName = f.replace(".java", "").replace(esPath.toString(), "")
.replace("/evosuite-tests/", "").replace(File.separator, ".");
.replace(File.separator,".").replace(".evosuite-tests.", "");
if (!qualifiedTestName.endsWith(EvoSuiteFacade.EVOSUITE_scaffolding_SUFFIX) && classesToGenerateTests
.contains(qualifiedTestName.replace(EvoSuiteFacade.EVOSUITE_SUFFIX, ""))) {
testGenerated.add(qualifiedTestName);
Expand All @@ -165,18 +168,21 @@ public TestCaseVariantValidationResult runTestFromEvoSuite(ProgramVariant curren

// WE COMPILE EVO TEST
log.info("Classpath " + classpathForCompile);

String envOS = System.getProperty("os.name");
String javaPath = ConfigurationProperties.getProperty("jvm4evosuitetestexecution");
List<String> command = new ArrayList<String>();
command.add(javaPath + File.separator + "javac");
if (!envOS.contains("Windows"))
command.add(javaPath + File.separator + "javac");
else
command.add("\"" + javaPath + File.separator + "javac" + "\"");
command.add("-classpath");
command.add(classpathForCompile);
command.add("-d");

//// Save compiled
File fout = new File(outPutTest);
fout.mkdirs();
command.add(outPutTest);
command.add(fout.getAbsolutePath());

// Adding the files
for (String testPath : pathTestGenerated) {
Expand All @@ -189,8 +195,8 @@ public TestCaseVariantValidationResult runTestFromEvoSuite(ProgramVariant curren
log.debug("Any test to generate, all test cases were generated before: " + testAlreadyGenerated);
}

String classpathForRunTest = classpathForCompile + (File.pathSeparator) + outPutTest + File.pathSeparator
+ System.getProperty("java.class.path");
String classpathForRunTest = classpathForCompile + (File.pathSeparator) + new File(outPutTest).getAbsolutePath()
+ File.pathSeparator + System.getProperty("java.class.path");
log.info("Process classpath " + classpathForRunTest);

ProcessEvoSuiteValidator evoProcess = new ProcessEvoSuiteValidator();
Expand Down Expand Up @@ -231,4 +237,4 @@ public TestCasesProgramValidationResult executeRegressionTesting(URL[] processCl
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;
Expand Down Expand Up @@ -49,11 +50,14 @@ public TestResult execute(String jvmPath, URL[] classpath, List<String> classesT
boolean outputInFile = ConfigurationProperties.getPropertyBool("processoutputinfile");

public TestResult execute(String jvmPath, String classpath, List<String> classesToExecute, int waitTime) {
String envOS = System.getProperty("os.name");
String timeZone = ConfigurationProperties.getProperty("timezone");

Process p = null;
jvmPath += File.separator + "java";
UUID procWinUUID = null;

String newJvmPath = jvmPath + File.separator + "java";
List<String> cls = new ArrayList<>(new HashSet(classesToExecute));

String newClasspath = classpath;
if (ConfigurationProperties.getPropertyBool("runjava7code") || ProjectConfiguration.isJDKLowerThan8()) {
newClasspath = (new File(ConfigurationProperties.getProperty("executorjar")).getAbsolutePath())
Expand All @@ -67,23 +71,36 @@ public TestResult execute(String jvmPath, String classpath, List<String> classes

List<String> command = new ArrayList<String>();

command.add(jvmPath);
command.add("\"" + newJvmPath + "\"");
command.add("-Xmx2048m");

String[] ids = ConfigurationProperties.getProperty(MetaGenerator.METALL).split(File.pathSeparator);
for (String mutid : ids) {
command.add("-D" + MetaGenerator.MUT_IDENTIFIER + mutid + "="
+ ConfigurationProperties.getProperty(MetaGenerator.MUT_IDENTIFIER + mutid));
}
if (envOS.contains("Windows")) {
procWinUUID = UUID.randomUUID();
command.add("-DwinProcUUID=" + procWinUUID);
System.setProperty("user.timezone", timeZone);
}

command.add("-cp");
command.add(newClasspath);
command.add("\"" + newClasspath + "\"");
command.add(laucherClassName().getCanonicalName());
command.addAll(cls);

printCommandToExecute(command, waitTime);

ProcessBuilder pb = new ProcessBuilder("/bin/bash");
ProcessBuilder pb;
if (!envOS.contains("Windows")) {
printCommandToExecute(command, waitTime);
pb = new ProcessBuilder("/bin/bash");
} else {
command.set(0, "'" + newJvmPath + "'");
command.set(5, "'" + newClasspath + "'");
// On Windows, BufferedWriter have a problem to write over 8192 characters.
// We must provide command in ProcessBuilder constructor.
pb = new ProcessBuilder("powershell", "-Command", "& " + toString(command));
}

if (outputInFile) {
pb.redirectOutput(ftemp);
Expand All @@ -97,22 +114,23 @@ public TestResult execute(String jvmPath, String classpath, List<String> classes
BufferedWriter p_stdin = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));

try {
// Set up the timezone
String timeZone = ConfigurationProperties.getProperty("timezone");
p_stdin.write("TZ=\"" + timeZone + "\"");
p_stdin.newLine();
p_stdin.flush();
p_stdin.write("export TZ");
p_stdin.newLine();
p_stdin.flush();
p_stdin.write("echo $TZ");
p_stdin.newLine();
p_stdin.flush();
// Writing the command
p_stdin.write(toString(command));

p_stdin.newLine();
p_stdin.flush();
if (!envOS.contains("Windows")) {
// Set up the timezone
p_stdin.write("TZ=\"" + timeZone + "\"");
p_stdin.newLine();
p_stdin.flush();
p_stdin.write("export TZ");
p_stdin.newLine();
p_stdin.flush();
p_stdin.write("echo $TZ");
p_stdin.newLine();
p_stdin.flush();
// Writing the command
p_stdin.write(toString(command));

p_stdin.newLine();
p_stdin.flush();
}

// end
p_stdin.write("exit");
Expand All @@ -125,13 +143,12 @@ public TestResult execute(String jvmPath, String classpath, List<String> classes

//
if (!p.waitFor(waitTime, TimeUnit.MILLISECONDS)) {
killProcess(p, waitTime);
killProcess(p, waitTime, procWinUUID);

return null;
}
long t_end = System.currentTimeMillis();
// log.debug("Execution time " + ((t_end - t_start) / 1000) + "
// seconds");
log.debug("Execution time " + ((t_end - t_start) / 1000) + "seconds");

if (!avoidInterruption) {
// We force obtaining the exit value.
Expand All @@ -143,12 +160,13 @@ public TestResult execute(String jvmPath, String classpath, List<String> classes
output = new BufferedReader(new FileReader(ftemp.getAbsolutePath()));
else
output = new BufferedReader(new InputStreamReader(p.getInputStream()));

TestResult tr = getTestResult(output);
p.destroyForcibly();
return tr;
} catch (IOException | InterruptedException | IllegalThreadStateException ex) {
log.info("The Process that runs JUnit test cases had problems: " + ex.getMessage());
killProcess(p, waitTime);
killProcess(p, waitTime, procWinUUID);
}
return null;
}
Expand All @@ -159,41 +177,62 @@ public TestResult execute(String jvmPath, String classpath, List<String> classes
*
* @param waitTime
*/
private void killProcess(Process p, int waitTime) {
private void killProcess(Process p, int waitTime, UUID procWinUUID) {
if (p == null)
return;

Object pid = null;
try {
Field f = p.getClass().getDeclaredField("pid");
f.setAccessible(true);
pid = f.get(p);
log.debug("-Killed id: pid->" + pid);

} catch (Exception e) {
if (procWinUUID != null) {
Process survivedPID = Runtime.getRuntime()
.exec("wmic process where \"commandline like '%-DwinProcUUID=" + procWinUUID
+ "%' and name like '%java.exe%'\" get processid");
BufferedReader outputSurvivedPIDs = new BufferedReader(
new InputStreamReader(survivedPID.getInputStream()));
String line;
int i = 0;
while ((line = outputSurvivedPIDs.readLine()) != null) {
if (i == 2 && !line.isEmpty()) {
pid = line.trim();
break;
}
i++;
}
} else {
Field f = p.getClass().getDeclaredField("pid");
f.setAccessible(true);
pid = f.get(p);
}
} catch (IOException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
log.error(e);
}
p.destroyForcibly();

p.destroyForcibly();
log.info("The Process that runs JUnit test cases did not terminate within waitTime of "
+ TimeUnit.MILLISECONDS.toSeconds(waitTime) + " seconds");
log.info("Killed the Process that runs JUnit test cases " + pid);
log.info("Killing the Process that runs JUnit test cases " + pid);

// workarrond!!
if (ConfigurationProperties.getPropertyBool("forcesubprocesskilling")) {
Integer subprocessid = Integer.valueOf(pid.toString()) + 1;
try {
log.debug("Killing subprocess " + subprocessid);
Process process = new ProcessBuilder(new String[] { "kill", subprocessid.toString() }).start();
Process process;
if (procWinUUID != null) {
log.error("Killing Windows process " + pid);
process = Runtime.getRuntime().exec("taskkill /T /F /PID " + pid);
} else {
log.debug("Killing subprocess " + subprocessid);
process = new ProcessBuilder(new String[] { "kill", subprocessid.toString() }).start();
}
process.waitFor();

} catch (Exception e) {
log.error("Problems killing subprocess " + subprocessid);
} catch (IOException | InterruptedException e) {
if (procWinUUID != null)
log.error("Problems killing Windows process " + pid);
else
log.error("Problems killing subprocess " + subprocessid);
log.error(e);
}

}

}

protected String urlArrayToString(URL[] urls) {
Expand Down Expand Up @@ -289,4 +328,4 @@ protected TestResult getTestResult(BufferedReader in) {
}
}

}
}
9 changes: 7 additions & 2 deletions src/main/java/fr/inria/astor/util/EvoSuiteFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ protected static URL[] redefineURL(File foutgen, URL[] originalURL) throws Malfo
* @return
*/
protected boolean runProcess(URL[] urlClasspath, String[] argumentsEvo) {
String envOS = System.getProperty("os.name");

Process p = null;

String javaPath = ConfigurationProperties.getProperty("jvm4evosuitetestexecution");
Expand All @@ -227,7 +229,10 @@ protected boolean runProcess(URL[] urlClasspath, String[] argumentsEvo) {
try {

List<String> command = new ArrayList<String>();
command.add(javaPath);
if (!envOS.contains("Windows"))
command.add(javaPath);
else
command.add("\"" + javaPath + "\"");
command.add("-jar");
command.add(new File(ConfigurationProperties.getProperty("evosuitejar")).getAbsolutePath());

Expand Down Expand Up @@ -439,4 +444,4 @@ public static void runProcess(String[] command) throws Exception {
logger.debug(command + " exitValue() " + pro.exitValue());
}

}
}
Loading
Loading