diff --git a/src/main/java/edu/washington/cs/dt/runners/AbstractTestRunner.java b/src/main/java/edu/washington/cs/dt/runners/AbstractTestRunner.java index 1d79cee..d117b2d 100644 --- a/src/main/java/edu/washington/cs/dt/runners/AbstractTestRunner.java +++ b/src/main/java/edu/washington/cs/dt/runners/AbstractTestRunner.java @@ -1,129 +1,143 @@ -/** Copyright 2012 University of Washington. All Rights Reserved. - * @author Sai Zhang - */ -package edu.washington.cs.dt.runners; - -import java.io.IOException; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import edu.washington.cs.dt.OneTestExecResult; -import edu.washington.cs.dt.RESULT; -import edu.washington.cs.dt.TestExecResults; -import edu.washington.cs.dt.main.Main; -import edu.washington.cs.dt.util.Files; -import edu.washington.cs.dt.util.Globals; -import edu.washington.cs.dt.util.TestExecUtils; -import edu.washington.cs.dt.util.Utils; - -public abstract class AbstractTestRunner { - - /* The input tests */ - protected final List junitTestList; - - /*keep the classpath needs to run the tests, tmp output file to keep the - * intermediate results*/ - protected String classPath = null; - protected String tmpOutputFile = null; - - /* Note that we use List here, since order matters*/ - public AbstractTestRunner(List tests) { - this.junitTestList = new LinkedList(); - this.junitTestList.addAll(tests); - this.classPath = System.getProperties().getProperty("java.class.path", null); - tmpOutputFile = Main.tmpfile; - } - - public AbstractTestRunner(String fileName) { - this(Files.readWholeNoExp(fileName)); - } - - public void setClassPath(String classPath) { - this.classPath = classPath; - } - - public String getClassPath() { - return this.classPath; - } - - public void setTmpOutputFile(String fileName) { - this.tmpOutputFile = fileName; - } - - public String getTmpOutputFile() { - return this.tmpOutputFile; - } - - public boolean isTestInList(String test) { - return this.junitTestList.contains(test); - } - - public abstract TestExecResults run(); - - protected void saveResultsToFile(Collection> results, String fileName) { - StringBuilder sb = new StringBuilder(); - int numOfPass = 0; - int numOfError = 0; - int numOfFail = 0; - for(Map result : results) { - for(String test : result.keySet()) { - RESULT r = result.get(test).result; - sb.append(test); - sb.append(" : "); - sb.append(r); - String fullStackTrace = result.get(test).getFullStackTrace(); - if(fullStackTrace != null && !fullStackTrace.trim().equals(TestExecUtils.noStackTrace)) { - sb.append(Globals.lineSep); - String[] sts = fullStackTrace.split(TestExecUtils.stackTraceSep); - for(String st : sts) { - sb.append(" "); - sb.append(st); - sb.append(Globals.lineSep); - } - } -// String filteredStack = result.get(test).getFilteredStackTrace(); -// if(filteredStack != null && !filteredStack.trim().equals(TestExecUtils.noStackTrace)) { -// sb.append(Globals.lineSep); -// String[] sts = filteredStack.split(TestExecUtils.stackTraceSep); -// for(String st : sts) { -// sb.append(" "); -// sb.append(st); -// sb.append(Globals.lineSep); -// } -// } - sb.append(Globals.lineSep); - if(r == RESULT.PASS) { - numOfPass++; - } else if (r == RESULT.ERROR) { - numOfError++; - } else if (r == RESULT.FAILURE) { - numOfFail ++; - } else { - throw new Error("Unknown: " + r); - } - } -// Utils.checkTrue(numOfPass + numOfError + numOfFail == result.size(), -// "Wrong number."); - } - sb.append("-----------------"); - sb.append(Globals.lineSep); - sb.append("Passing tests: " + numOfPass); - sb.append(Globals.lineSep); - sb.append("Failing tests: " + numOfFail); - sb.append(Globals.lineSep); - sb.append("Error tests: " + numOfError); - sb.append(Globals.lineSep); - try { - Files.writeToFile(sb.toString(), fileName); - } catch (IOException e) { - throw new Error(e); - } - } - - protected void saveResultsToFile(Map result, String fileName) { - this.saveResultsToFile(Collections.singletonList(result), fileName); - } -} +/** Copyright 2012 University of Washington. All Rights Reserved. + * @author Sai Zhang + */ +package edu.washington.cs.dt.runners; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import edu.washington.cs.dt.OneTestExecResult; +import edu.washington.cs.dt.RESULT; +import edu.washington.cs.dt.TestExecResults; +import edu.washington.cs.dt.main.Main; +import edu.washington.cs.dt.util.Files; +import edu.washington.cs.dt.util.Globals; +import edu.washington.cs.dt.util.TestExecUtils; +import edu.washington.cs.dt.util.Utils; + +public abstract class AbstractTestRunner { + + /* The input tests */ + protected final List junitTestList; + + /*keep the classpath needs to run the tests, tmp output file to keep the + * intermediate results*/ + protected String classPath = null; + protected String tmpOutputFile = null; + protected String threadnum = ""; + + /* Note that we use List here, since order matters*/ + public AbstractTestRunner(List tests) { + this.junitTestList = new LinkedList(); + this.junitTestList.addAll(tests); + this.classPath = System.getProperties().getProperty("java.class.path", null); + tmpOutputFile = Main.tmpfile; + } + //overloaded with tmpfilepath argument (the number of threads is passed in for this) + public AbstractTestRunner(List tests, String tmpfilepath) { + this.junitTestList = new LinkedList(); + this.junitTestList.addAll(tests); + this.classPath = System.getProperties().getProperty("java.class.path", null); + tmpOutputFile = (Main.tmpfile)+tmpfilepath; + this.threadnum = tmpfilepath; + } + public String getThreadnum() + { + return this.threadnum; + } + + public AbstractTestRunner(String fileName) { + this(Files.readWholeNoExp(fileName)); + } + + public void setClassPath(String classPath) { + this.classPath = classPath; + } + + public String getClassPath() { + return this.classPath; + } + + public void setTmpOutputFile(String fileName) { + this.tmpOutputFile = fileName; + } + + public String getTmpOutputFile() { + return this.tmpOutputFile; + } + + public boolean isTestInList(String test) { + return this.junitTestList.contains(test); + } + + public abstract TestExecResults run(); + + protected void saveResultsToFile(Collection> results, String fileName) { + StringBuilder sb = new StringBuilder(); + int numOfPass = 0; + int numOfError = 0; + int numOfFail = 0; + for(Map result : results) { + for(String test : result.keySet()) { + RESULT r = result.get(test).result; + sb.append(test); + sb.append(" : "); + sb.append(r); + String fullStackTrace = result.get(test).getFullStackTrace(); + if(fullStackTrace != null && !fullStackTrace.trim().equals(TestExecUtils.noStackTrace)) { + sb.append(Globals.lineSep); + String[] sts = fullStackTrace.split(TestExecUtils.stackTraceSep); + for(String st : sts) { + sb.append(" "); + sb.append(st); + sb.append(Globals.lineSep); + } + } +// String filteredStack = result.get(test).getFilteredStackTrace(); +// if(filteredStack != null && !filteredStack.trim().equals(TestExecUtils.noStackTrace)) { +// sb.append(Globals.lineSep); +// String[] sts = filteredStack.split(TestExecUtils.stackTraceSep); +// for(String st : sts) { +// sb.append(" "); +// sb.append(st); +// sb.append(Globals.lineSep); +// } +// } + sb.append(Globals.lineSep); + if(r == RESULT.PASS) { + numOfPass++; + } else if (r == RESULT.ERROR) { + numOfError++; + } else if (r == RESULT.FAILURE) { + numOfFail ++; + } else { + throw new Error("Unknown: " + r); + } + } +// Utils.checkTrue(numOfPass + numOfError + numOfFail == result.size(), +// "Wrong number."); + } + sb.append("-----------------"); + sb.append(Globals.lineSep); + sb.append("Passing tests: " + numOfPass); + sb.append(Globals.lineSep); + sb.append("Failing tests: " + numOfFail); + sb.append(Globals.lineSep); + sb.append("Error tests: " + numOfError); + sb.append(Globals.lineSep); + try { + Files.writeToFile(sb.toString(), fileName); + } catch (IOException e) { + throw new Error(e); + } + } + + protected void saveResultsToFile(Map result, String fileName) { + this.saveResultsToFile(Collections.singletonList(result), fileName); + } +} + diff --git a/src/main/java/edu/washington/cs/dt/runners/FixedOrderRunner.java b/src/main/java/edu/washington/cs/dt/runners/FixedOrderRunner.java index 16348c9..ba5b574 100644 --- a/src/main/java/edu/washington/cs/dt/runners/FixedOrderRunner.java +++ b/src/main/java/edu/washington/cs/dt/runners/FixedOrderRunner.java @@ -1,38 +1,47 @@ -/** Copyright 2012 University of Washington. All Rights Reserved. - * @author Sai Zhang - */ -package edu.washington.cs.dt.runners; - -import java.util.List; -import java.util.Map; - -import edu.washington.cs.dt.OneTestExecResult; -import edu.washington.cs.dt.TestExecResults; -import edu.washington.cs.dt.main.Main; -import edu.washington.cs.dt.util.TestExecUtils; - -public class FixedOrderRunner extends AbstractTestRunner { - - public FixedOrderRunner(List tests) { - super(tests); - } - - public FixedOrderRunner(String fileName) { - super(fileName); - } - - @Override - public TestExecResults run() { - System.out.println("Executing fixed runner now."); - - TestExecResults result = TestExecResults.createInstance(); - Map singleRun = TestExecUtils.executeTestsInFreshJVM(super.getClassPath(), - super.getTmpOutputFile(), super.junitTestList); - result.addExecutionResults(singleRun); - //check do we need to dump the fixed ordered results to an intermediate file - if(Main.fixedOrderReport != null) { - super.saveResultsToFile(singleRun, Main.fixedOrderReport); - } - return result; - } -} +/** Copyright 2012 University of Washington. All Rights Reserved. + * @author Sai Zhang + */ +package edu.washington.cs.dt.runners; + +import java.util.List; +import java.util.Map; + +import edu.washington.cs.dt.OneTestExecResult; +import edu.washington.cs.dt.TestExecResults; +import edu.washington.cs.dt.main.Main; +import edu.washington.cs.dt.util.TestExecUtils; + +public class FixedOrderRunner extends AbstractTestRunner { + + public FixedOrderRunner(List tests) { + super(tests); + } + //overloaded + public FixedOrderRunner(List tests, String tmpfilepath) { + super(tests, tmpfilepath); + } + + public FixedOrderRunner(String fileName) { + super(fileName); + } + + @Override + public TestExecResults run() { + System.out.println("Executing fixed runner now."); + + TestExecResults result = TestExecResults.createInstance(); + //Map singleRun = TestExecUtils.executeTestsInFreshJVM(super.getClassPath(), + //super.getTmpOutputFile(), super.junitTestList); + + TestExecUtils util = new TestExecUtils(); + Map singleRun = util.executeTestsInFreshJVM(super.getClassPath(), + super.getTmpOutputFile(), super.junitTestList, super.getThreadnum()); + + result.addExecutionResults(singleRun); + //check do we need to dump the fixed ordered results to an intermediate file + if(Main.fixedOrderReport != null) { + super.saveResultsToFile(singleRun, Main.fixedOrderReport); + } + return result; + } +} diff --git a/src/main/java/edu/washington/cs/dt/util/TestExecUtils.java b/src/main/java/edu/washington/cs/dt/util/TestExecUtils.java index dfd3140..614a34b 100644 --- a/src/main/java/edu/washington/cs/dt/util/TestExecUtils.java +++ b/src/main/java/edu/washington/cs/dt/util/TestExecUtils.java @@ -1,243 +1,347 @@ -/** Copyright 2012 University of Washington. All Rights Reserved. - * @author Sai Zhang - */ -package edu.washington.cs.dt.util; - -import java.io.File; -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import junit.framework.TestFailure; -import plume.Option; -import edu.washington.cs.dt.OneTestExecResult; -import edu.washington.cs.dt.RESULT; -import edu.washington.cs.dt.main.Main; - - -public class TestExecUtils { - - public static String testResultSep = "#"; - - public static String resultExcepSep = "%#%#"; - - public static String timeSep = "?"; - - public static String noStackTrace = "NO_STACK_TRACE_FOR_A_PASSING_TEST"; - - @Option("The temp file to store all tests to execute") - public static String testsfile = "./tmptestfiles.txt"; - - @Option("The min number of tests when using ./tmptestfiles") - public static int threshhold = 120; - public static String lockFile = "LOCK_FILE"; - public static String exitFileName = "EXIT_FILE"; - - public static boolean fork_test_execution = true; - - /* - * Executes a list of tests in order by launching a fresh JVM, and - * returns the result of each test. - * - * The test is in the form of packageName.className.methodName - * */ - public static Map executeTestsInFreshJVM(String classPath, String outputFile, List tests) { - if (fork_test_execution) { - return executeTestsInFreshJVMForkTestExecution(classPath, outputFile, tests); - } else { - List commandList = new LinkedList(); - Files.createIfNotExistNoExp(testsfile); - Files.writeToFileWithNoExp(tests, testsfile); - commandList.add(outputFile); - commandList.add(testsfile); - commandList.add("true"); - - String[] args = commandList.toArray(new String[0]); - int testsExecuted = 0; - Map testResults = null; - try { - testsExecuted = TestRunnerWrapperFileInputs.runTests(args); - testResults = parseTestResults(outputFile); - - File exitFile = new File(exitFileName); - File file = new File(lockFile); - file.delete(); - exitFile.delete(); - File tmpFile = new File(outputFile); - File tmpTestfile = new File(testsfile); - tmpFile.delete(); - tmpTestfile.delete(); - } catch (IOException e) { - e.printStackTrace(); - } - Utils.checkTrue(testsExecuted == testResults.size(), "Test num not equal. Results is size " + testResults.size() + ". Tests is size " + testsExecuted + "."); - return testResults; - } - } - - public static Map executeTestsInFreshJVMForkTestExecution(String classPath, String outputFile, List tests) { - - List commandList = new LinkedList(); - commandList.add("java"); - commandList.add("-cp"); - commandList.add(classPath + Globals.pathSep + System.getProperties().getProperty("java.class.path", null)); - -// if(tests.size() < threshhold) { -// commandList.add("edu.washington.cs.dt.util.TestRunnerWrapper"); -// commandList.add(outputFile); -// commandList.addAll(tests); -// } else { - Files.createIfNotExistNoExp(testsfile); - Files.writeToFileWithNoExp(tests, testsfile); - - commandList.add("edu.washington.cs.dt.util.TestRunnerWrapperFileInputs"); - commandList.add(outputFile); - commandList.add(testsfile); -// } - - String[] args = commandList.toArray(new String[0]); - - File exitFile = new File(exitFileName); - File file = new File(lockFile); - try{ - file.delete(); - exitFile.delete(); - }catch(Exception e){ - e.printStackTrace(); - } - - Process proc = Command.execProc(args, System.out, "", false); - - while (!file.exists() && !exitFile.exists()) { - try { - Thread.sleep(1000); - } catch(InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - - proc.destroy(); - - if (exitFile.exists()) { - try { - file.delete(); - exitFile.delete(); - } catch(Exception e){ - e.printStackTrace(); - } - System.err.println("Exit file detected."); - System.exit(0); - } else { - try { - file.delete(); - exitFile.delete(); - } catch(Exception e){ - e.printStackTrace(); - } - } - - Map testResults = parseTestResults(outputFile); - - Utils.checkTrue(tests.size() == testResults.size(), "Test num not equal. Results is size " + testResults.size() + ". Tests is size " + tests.size() + "."); - - return testResults; - } - - static Map parseTestResults(String outputFile) { - Map ret = new LinkedHashMap(); - - List lines = Files.readWholeNoExp(outputFile); - - for(String line : lines) { - int resultSepIndex = line.indexOf(TestExecUtils.testResultSep); - int excepSepIndex = line.indexOf(TestExecUtils.resultExcepSep); - int timeSepIndex = line.indexOf(timeSep); - Utils.checkTrue(resultSepIndex != -1, "resultSepIndex != -1"); - Utils.checkTrue(excepSepIndex != -1, "excepSepIndex != -1"); - Utils.checkTrue(timeSepIndex != -1, "timeSepIndex != -1"); - - String testCase = line.substring(0, timeSepIndex); - String time = line.substring(timeSepIndex + timeSep.length(), resultSepIndex); - String result = line.substring(resultSepIndex + TestExecUtils.testResultSep.length(), excepSepIndex); - String fullStacktrace = line.substring(excepSepIndex + TestExecUtils.resultExcepSep.length(), line.length()); - if(result.equals(RESULT.PASS.name())) { - OneTestExecResult r = new OneTestExecResult(RESULT.PASS, fullStacktrace, Long.parseLong(time)); - ret.put(testCase, r); - } else if (result.equals(RESULT.FAILURE.name())) { - OneTestExecResult r = new OneTestExecResult(RESULT.FAILURE, fullStacktrace, Long.parseLong(time)); - ret.put(testCase, r); - } else if (result.equals(RESULT.ERROR.name())) { - OneTestExecResult r = new OneTestExecResult(RESULT.ERROR, fullStacktrace, Long.parseLong(time)); - ret.put(testCase, r); - } else { - throw new RuntimeException("Unknown result: " + result); - } - } - - return ret; - } - - public static final String JUNIT_ASSERT = "junit.framework.Assert"; - - public static String flatStackTrace(TestFailure failure, String excludeRegex) { - Pattern p = Pattern.compile(excludeRegex); - Throwable t = failure.thrownException(); - String[] stackTraces = extractStackTraces(t); - String flatString = flatStrings(stackTraces, p, JUNIT_ASSERT); - return flatString; - } - - public static String stackTraceSep = " - "; - - public static String flatStrings(String[] strs, Pattern excludeRegex, String exceptedPrefix) { - StringBuilder sb = new StringBuilder(); - for(String str : strs) { - if(shouldExclude(str, excludeRegex, exceptedPrefix)) { - continue; - } - if(str.startsWith("edu.washington.cs.dt")) { - continue; - } - sb.append(str); - // sb.append(" - "); - sb.append(stackTraceSep); - } - return sb.toString(); - } - - public static String flatStrings(String[] strs) { - StringBuilder sb = new StringBuilder(); - for(String str : strs) { - sb.append(str); - sb.append(stackTraceSep); - } - return sb.toString(); - } - - public static String flatFilteredStackTraces(String fullStackTrace) { - String[] elements = fullStackTrace.split(stackTraceSep); - Pattern p = Pattern.compile(Main.excludeRegex); - String flatString = TestExecUtils.flatStrings(elements, p, TestExecUtils.JUNIT_ASSERT); - return flatString; - } - - public static String[] extractStackTraces(Throwable t) { - String[] traces = new String[t.getStackTrace().length]; - for(int i = 0; i < t.getStackTrace().length; i++) { - traces[i] = t.getStackTrace()[i].toString().trim(); - } - return traces; - } - - public static boolean shouldExclude(String target, Pattern p, String exceptedPrefix) { - Matcher m = p.matcher(target); - if( m.find() && !(target.startsWith(exceptedPrefix))) { - return true; - } - return false; - } -} \ No newline at end of file +/** Copyright 2012 University of Washington. All Rights Reserved. + * @author Sai Zhang + */ +package edu.washington.cs.dt.util; + +import java.io.File; +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import junit.framework.TestFailure; +import plume.Option; +import edu.washington.cs.dt.OneTestExecResult; +import edu.washington.cs.dt.RESULT; +import edu.washington.cs.dt.main.Main; + + +public class TestExecUtils { + + public static String testResultSep = "#"; + + public static String resultExcepSep = "%#%#"; + + public static String timeSep = "?"; + + public static String noStackTrace = "NO_STACK_TRACE_FOR_A_PASSING_TEST"; + + @Option("The temp file to store all tests to execute") + public static String testsfile = "./tmptestfiles.txt"; + + @Option("The min number of tests when using ./tmptestfiles") + public static int threshhold = 120; + public static String lockFile = "LOCK_FILE"; + public static String exitFileName = "EXIT_FILE"; + + public static boolean fork_test_execution = true; + + public Map executeTestsInFreshJVM(String classPath, String outputFile, List tests, String append) { + if (fork_test_execution) { + return executeTestsInFreshJVMForkTestExecution(classPath, outputFile, tests, append); + } else { + List commandList = new LinkedList(); + Files.createIfNotExistNoExp(testsfile+append); + Files.writeToFileWithNoExp(tests, testsfile+append); + commandList.add(outputFile); + commandList.add(testsfile+append); + commandList.add("true"); + + String[] args = commandList.toArray(new String[0]); + int testsExecuted = 0; + Map testResults = null; + try { + testsExecuted = TestRunnerWrapperFileInputs.runTests(args); + testResults = parseTestResults(outputFile); + + File exitFile = new File(exitFileName+append); + File file = new File(lockFile+append); + file.delete(); + exitFile.delete(); + File tmpFile = new File(outputFile); + File tmpTestfile = new File(testsfile+append); + tmpFile.delete(); + tmpTestfile.delete(); + } catch (IOException e) { + e.printStackTrace(); + } + Utils.checkTrue(testsExecuted == testResults.size(), "Test num not equal. Results is size " + testResults.size() + ". Tests is size " + testsExecuted + "."); + return testResults; + } + } + public Map executeTestsInFreshJVMForkTestExecution(String classPath, String outputFile, List tests, String append) { + + List commandList = new LinkedList(); + commandList.add("java"); + commandList.add("-cp"); + commandList.add(classPath + Globals.pathSep + System.getProperties().getProperty("java.class.path", null)); + +// if(tests.size() < threshhold) { +// commandList.add("edu.washington.cs.dt.util.TestRunnerWrapper"); +// commandList.add(outputFile); +// commandList.addAll(tests); +// } else { + Files.createIfNotExistNoExp(testsfile+append); + Files.writeToFileWithNoExp(tests, testsfile+append); + + commandList.add("edu.washington.cs.dt.util.TestRunnerWrapperFileInputs"); + commandList.add(outputFile); + commandList.add(testsfile+append); + + commandList.add(append); +// } + + String[] args = commandList.toArray(new String[0]); + + File exitFile = new File(exitFileName+append); + File file = new File(lockFile+append); + try{ + file.delete(); + exitFile.delete(); + }catch(Exception e){ + e.printStackTrace(); + } + + Process proc = Command.execProc(args, System.out, "", false); + + while (!file.exists() && !exitFile.exists()) { + try { + Thread.sleep(1000); + } catch(InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + + proc.destroy(); + + if (exitFile.exists()) { + try { + file.delete(); + exitFile.delete(); + } catch(Exception e){ + e.printStackTrace(); + } + System.err.println("Exit file detected."); + System.exit(0); + } else { + try { + file.delete(); + exitFile.delete(); + } catch(Exception e){ + e.printStackTrace(); + } + } + + Map testResults = parseTestResults(outputFile); + + Utils.checkTrue(tests.size() == testResults.size(), "Test num not equal. Results is size " + testResults.size() + ". Tests is size " + tests.size() + "."); + + return testResults; + } + + + /* + * Executes a list of tests in order by launching a fresh JVM, and + * returns the result of each test. + * + * The test is in the form of packageName.className.methodName + * */ + public static Map executeTestsInFreshJVM(String classPath, String outputFile, List tests) { + if (fork_test_execution) { + return executeTestsInFreshJVMForkTestExecution(classPath, outputFile, tests); + } else { + List commandList = new LinkedList(); + Files.createIfNotExistNoExp(testsfile); + Files.writeToFileWithNoExp(tests, testsfile); + commandList.add(outputFile); + commandList.add(testsfile); + commandList.add("true"); + + String[] args = commandList.toArray(new String[0]); + int testsExecuted = 0; + Map testResults = null; + try { + testsExecuted = TestRunnerWrapperFileInputs.runTests(args); + testResults = parseTestResults(outputFile); + + File exitFile = new File(exitFileName); + File file = new File(lockFile); + file.delete(); + exitFile.delete(); + File tmpFile = new File(outputFile); + File tmpTestfile = new File(testsfile); + tmpFile.delete(); + tmpTestfile.delete(); + } catch (IOException e) { + e.printStackTrace(); + } + Utils.checkTrue(testsExecuted == testResults.size(), "Test num not equal. Results is size " + testResults.size() + ". Tests is size " + testsExecuted + "."); + return testResults; + } + } + + public static Map executeTestsInFreshJVMForkTestExecution(String classPath, String outputFile, List tests) { + + List commandList = new LinkedList(); + commandList.add("java"); + commandList.add("-cp"); + commandList.add(classPath + Globals.pathSep + System.getProperties().getProperty("java.class.path", null)); + +// if(tests.size() < threshhold) { +// commandList.add("edu.washington.cs.dt.util.TestRunnerWrapper"); +// commandList.add(outputFile); +// commandList.addAll(tests); +// } else { + Files.createIfNotExistNoExp(testsfile); + Files.writeToFileWithNoExp(tests, testsfile); + + commandList.add("edu.washington.cs.dt.util.TestRunnerWrapperFileInputs"); + commandList.add(outputFile); + commandList.add(testsfile); +// } + + String[] args = commandList.toArray(new String[0]); + + File exitFile = new File(exitFileName); + File file = new File(lockFile); + try{ + file.delete(); + exitFile.delete(); + }catch(Exception e){ + e.printStackTrace(); + } + + Process proc = Command.execProc(args, System.out, "", false); + + while (!file.exists() && !exitFile.exists()) { + try { + Thread.sleep(1000); + } catch(InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + + proc.destroy(); + + if (exitFile.exists()) { + try { + file.delete(); + exitFile.delete(); + } catch(Exception e){ + e.printStackTrace(); + } + System.err.println("Exit file detected."); + System.exit(0); + } else { + try { + file.delete(); + exitFile.delete(); + } catch(Exception e){ + e.printStackTrace(); + } + } + + Map testResults = parseTestResults(outputFile); + + Utils.checkTrue(tests.size() == testResults.size(), "Test num not equal. Results is size " + testResults.size() + ". Tests is size " + tests.size() + "."); + + return testResults; + } + + static Map parseTestResults(String outputFile) { + Map ret = new LinkedHashMap(); + + List lines = Files.readWholeNoExp(outputFile); + + for(String line : lines) { + int resultSepIndex = line.indexOf(TestExecUtils.testResultSep); + int excepSepIndex = line.indexOf(TestExecUtils.resultExcepSep); + int timeSepIndex = line.indexOf(timeSep); + Utils.checkTrue(resultSepIndex != -1, "resultSepIndex != -1"); + Utils.checkTrue(excepSepIndex != -1, "excepSepIndex != -1"); + Utils.checkTrue(timeSepIndex != -1, "timeSepIndex != -1"); + + String testCase = line.substring(0, timeSepIndex); + String time = line.substring(timeSepIndex + timeSep.length(), resultSepIndex); + String result = line.substring(resultSepIndex + TestExecUtils.testResultSep.length(), excepSepIndex); + String fullStacktrace = line.substring(excepSepIndex + TestExecUtils.resultExcepSep.length(), line.length()); + if(result.equals(RESULT.PASS.name())) { + OneTestExecResult r = new OneTestExecResult(RESULT.PASS, fullStacktrace, Long.parseLong(time)); + ret.put(testCase, r); + } else if (result.equals(RESULT.FAILURE.name())) { + OneTestExecResult r = new OneTestExecResult(RESULT.FAILURE, fullStacktrace, Long.parseLong(time)); + ret.put(testCase, r); + } else if (result.equals(RESULT.ERROR.name())) { + OneTestExecResult r = new OneTestExecResult(RESULT.ERROR, fullStacktrace, Long.parseLong(time)); + ret.put(testCase, r); + } else { + throw new RuntimeException("Unknown result: " + result); + } + } + + return ret; + } + + public static final String JUNIT_ASSERT = "junit.framework.Assert"; + + public static String flatStackTrace(TestFailure failure, String excludeRegex) { + Pattern p = Pattern.compile(excludeRegex); + Throwable t = failure.thrownException(); + String[] stackTraces = extractStackTraces(t); + String flatString = flatStrings(stackTraces, p, JUNIT_ASSERT); + return flatString; + } + + public static String stackTraceSep = " - "; + + public static String flatStrings(String[] strs, Pattern excludeRegex, String exceptedPrefix) { + StringBuilder sb = new StringBuilder(); + for(String str : strs) { + if(shouldExclude(str, excludeRegex, exceptedPrefix)) { + continue; + } + if(str.startsWith("edu.washington.cs.dt")) { + continue; + } + sb.append(str); + // sb.append(" - "); + sb.append(stackTraceSep); + } + return sb.toString(); + } + + public static String flatStrings(String[] strs) { + StringBuilder sb = new StringBuilder(); + for(String str : strs) { + sb.append(str); + sb.append(stackTraceSep); + } + return sb.toString(); + } + + public static String flatFilteredStackTraces(String fullStackTrace) { + String[] elements = fullStackTrace.split(stackTraceSep); + Pattern p = Pattern.compile(Main.excludeRegex); + String flatString = TestExecUtils.flatStrings(elements, p, TestExecUtils.JUNIT_ASSERT); + return flatString; + } + + public static String[] extractStackTraces(Throwable t) { + String[] traces = new String[t.getStackTrace().length]; + for(int i = 0; i < t.getStackTrace().length; i++) { + traces[i] = t.getStackTrace()[i].toString().trim(); + } + return traces; + } + + public static boolean shouldExclude(String target, Pattern p, String exceptedPrefix) { + Matcher m = p.matcher(target); + if( m.find() && !(target.startsWith(exceptedPrefix))) { + return true; + } + return false; + } +} diff --git a/src/main/java/edu/washington/cs/dt/util/TestRunnerWrapperFileInputs.java b/src/main/java/edu/washington/cs/dt/util/TestRunnerWrapperFileInputs.java index a570536..f4b6382 100644 --- a/src/main/java/edu/washington/cs/dt/util/TestRunnerWrapperFileInputs.java +++ b/src/main/java/edu/washington/cs/dt/util/TestRunnerWrapperFileInputs.java @@ -1,105 +1,105 @@ -/** Copyright 2012 University of Washington. All Rights Reserved. - * @author Sai Zhang - */ -package edu.washington.cs.dt.util; - -import java.io.File; -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; - -/** - * Beaware, also need to change TestRunnerWrapper - * */ - -public class TestRunnerWrapperFileInputs { - /* - * args[0]: the result output file - * args[1]: a file containing all tests - * */ - public static void main(String[] args) throws IOException { - runTests(args); - } - public static int runTests(String[] args) throws IOException { - if(args.length < 2) { - System.err.println("The arg number must be at least 2: args[0] " + - "is the output file, args[1] is the file containing all unit tests." - + "args[2] is optional to check whether there are incompatible tests and" - + "skips them."); - System.exit(2); - } - /*parse the argument*/ - String outputFile = args[0]; - List content = Files.readWholeNoExp(args[1]); - boolean skipIncompatibleTests = false; - if (args.length > 2) { - skipIncompatibleTests = Boolean.parseBoolean(args[2]); - } - List tests = new LinkedList(); - for(String line : content) { - if(!line.trim().equals("")) { - tests.add(line.trim()); - } - } - - int testsExecuted = 0; - /*create the StringBuilder to output results*/ - StringBuilder sb = new StringBuilder(); - for(String fullTestName : tests) { - System.out.println("Test being executed: " + fullTestName); - - /*check the results*/ - String result = null; - // String stackTrace = TestExecUtils.noStackTrace; - String fullStackTrace = TestExecUtils.noStackTrace; - - JUnitTestExecutor executor = null; - try { - executor = new JUnitTestExecutor(fullTestName); - } catch (ClassNotFoundException e) { - Files.writeToFile("", TestExecUtils.exitFileName); - e.printStackTrace(); - System.exit(0); - } - - if (skipIncompatibleTests && !executor.isClassCompatible()) { - System.out.println(" Detected incompatible test case with RunWith annotation."); - continue; - } - - testsExecuted += 1; - long start = System.nanoTime(); - executor.executeWithJUnit4Runner(); - long interval = System.nanoTime() - start; - result = executor.getResult(); - // stackTrace = executor.getStackTrace(); - fullStackTrace = executor.getFullStackTrace(); - - sb.append(fullTestName); - sb.append(TestExecUtils.timeSep); - sb.append(interval); - sb.append(TestExecUtils.testResultSep); - sb.append(result); - sb.append(TestExecUtils.resultExcepSep); - // sb.append(stackTrace); - sb.append(fullStackTrace); - sb.append(Globals.lineSep); - } - //if not exist, create it - File f = new File(outputFile); - if(!f.exists()) { - File dir = f.getParentFile(); - boolean created = true; - if(dir != null && !dir.exists()) { - created = dir.mkdirs(); - } - created = created & f.createNewFile(); - if(!created) { - throw new RuntimeException("Cannot create: " + outputFile); - } - } - Files.writeToFile(sb.toString(), outputFile); - Files.writeToFile("", TestExecUtils.lockFile); - return testsExecuted; - } -} +/** Copyright 2012 University of Washington. All Rights Reserved. + * @author Sai Zhang + */ +package edu.washington.cs.dt.util; + +import java.io.File; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +/** + * Beaware, also need to change TestRunnerWrapper + * */ + +public class TestRunnerWrapperFileInputs { + /* + * args[0]: the result output file + * args[1]: a file containing all tests + * */ + public static void main(String[] args) throws IOException { + runTests(args); + } + public static int runTests(String[] args) throws IOException { + if(args.length < 2) { + System.err.println("The arg number must be at least 2: args[0] " + + "is the output file, args[1] is the file containing all unit tests." + + "args[2] is optional to check whether there are incompatible tests and" + + "skips them."); + System.exit(2); + } + /*parse the argument*/ + String outputFile = args[0]; + List content = Files.readWholeNoExp(args[1]); + boolean skipIncompatibleTests = false; + if (args.length > 3) { + skipIncompatibleTests = Boolean.parseBoolean(args[3]); + } + List tests = new LinkedList(); + for(String line : content) { + if(!line.trim().equals("")) { + tests.add(line.trim()); + } + } + + int testsExecuted = 0; + /*create the StringBuilder to output results*/ + StringBuilder sb = new StringBuilder(); + for(String fullTestName : tests) { + System.out.println("Test being executed: " + fullTestName); + + /*check the results*/ + String result = null; + // String stackTrace = TestExecUtils.noStackTrace; + String fullStackTrace = TestExecUtils.noStackTrace; + + JUnitTestExecutor executor = null; + try { + executor = new JUnitTestExecutor(fullTestName); + } catch (ClassNotFoundException e) { + Files.writeToFile("", TestExecUtils.exitFileName+args[2]); + e.printStackTrace(); + System.exit(0); + } + + if (skipIncompatibleTests && !executor.isClassCompatible()) { + System.out.println(" Detected incompatible test case with RunWith annotation."); + continue; + } + + testsExecuted += 1; + long start = System.nanoTime(); + executor.executeWithJUnit4Runner(); + long interval = System.nanoTime() - start; + result = executor.getResult(); + // stackTrace = executor.getStackTrace(); + fullStackTrace = executor.getFullStackTrace(); + + sb.append(fullTestName); + sb.append(TestExecUtils.timeSep); + sb.append(interval); + sb.append(TestExecUtils.testResultSep); + sb.append(result); + sb.append(TestExecUtils.resultExcepSep); + // sb.append(stackTrace); + sb.append(fullStackTrace); + sb.append(Globals.lineSep); + } + //if not exist, create it + File f = new File(outputFile); + if(!f.exists()) { + File dir = f.getParentFile(); + boolean created = true; + if(dir != null && !dir.exists()) { + created = dir.mkdirs(); + } + created = created & f.createNewFile(); + if(!created) { + throw new RuntimeException("Cannot create: " + outputFile); + } + } + Files.writeToFile(sb.toString(), outputFile); + Files.writeToFile("", TestExecUtils.lockFile+args[2]); + return testsExecuted; + } +}