View Javadoc
1 /* ForkTest.java */ 2 3 package org.quilt.frontend.ant; 4 5 import org.apache.tools.ant.BuildException; 6 import org.apache.tools.ant.Project; 7 import org.apache.tools.ant.Task; 8 import org.apache.tools.ant.taskdefs.Execute; 9 import org.apache.tools.ant.taskdefs.ExecuteWatchdog; // need this 10 import org.apache.tools.ant.taskdefs.LogStreamHandler; 11 import org.apache.tools.ant.types.CommandlineJava; 12 import org.apache.tools.ant.types.EnumeratedAttribute; 13 import org.apache.tools.ant.types.Environment; 14 import org.apache.tools.ant.types.Path; 15 import org.apache.tools.ant.util.FileUtils; 16 17 import java.io.File; 18 import java.io.FileOutputStream; 19 import java.io.IOException; 20 import java.io.OutputStream; 21 22 import java.util.Enumeration; 23 import java.util.Hashtable; 24 import java.util.Properties; 25 import java.util.Vector; 26 27 import junit.framework.AssertionFailedError; 28 import junit.framework.Test; 29 import junit.framework.TestResult; 30 31 import org.quilt.framework.*; 32 import org.quilt.reports.*; 33 34 // ////////////////////////////////////////////////////////////////// 35 // NEEDS LOTS OF ATTENTION ////////////////////////////////////////// 36 // ////////////////////////////////////////////////////////////////// 37 // 38 /*** 39 * Run an individual test in a separate JVM. Search on Bug 23150; 40 * needs to return correct status code if interrupted or times out. 41 */ 42 public class ForkTest { 43 44 private Project project = null; 45 private Task task = null; 46 private TaskControl tc = null; 47 private QuiltTest qt = null; 48 private boolean mockery = false; 49 private boolean checkingCoverage = false; 50 51 /*** No-arg constructor. */ 52 public ForkTest() { } 53 54 /*** 55 * Fork an individual test, running it in a separate Java virtual 56 * machine. 57 * 58 * @param qt Data structure holding test parameters. 59 * @param tc Structure holding parameters for the entire run. 60 * @param watchdog Sets timeout in ms for this test. 61 */ 62 protected int execTest (QuiltTest qt, TaskControl tc, 63 ExecuteWatchdog watchdog) throws BuildException { 64 65 this.tc = tc; 66 task = tc.getTask(); 67 project = task.getProject(); 68 mockery = qt.getMockTestRun(); 69 checkingCoverage = qt.getCheckCoverage(); 70 71 CommandlineJava cmd = (CommandlineJava) tc.getCommandline().clone(); 72 73 if (mockery) { 74 task.log("ForkTest: setting class name to MockTestRunner"); 75 cmd.setClassname( "org.quilt.textui.MockTestRunner"); 76 } else { 77 cmd.setClassname( "org.quilt.textui.TestRunner"); 78 } 79 // ////////////////////////////////////////////////////////// 80 // THIS INTERFACE MUST BE KEPT IN SYNC WITH textui.TestRunner 81 // and textui.MockTestRunner 82 // ////////////////////////////////////////////////////////// 83 cmd.createArgument().setValue(qt.getName()); 84 cmd.createArgument().setValue("checkCoverage=" + checkingCoverage); 85 if (checkingCoverage) { 86 String excluded = qt.getCheckExcludes(); 87 String included = qt.getCheckIncludes(); 88 if (excluded != null ) { 89 cmd.createArgument().setValue( 90 "checkExcludes=" + excluded); 91 } 92 if (included != null ) { 93 cmd.createArgument().setValue( 94 "checkIncludes=" + included); 95 } 96 } 97 cmd.createArgument().setValue("filtertrace=" 98 + qt.getFiltertrace()); 99 cmd.createArgument().setValue("haltOnError=" 100 + qt.getHaltOnError()); 101 cmd.createArgument().setValue("haltOnFailure=" 102 + qt.getHaltOnFailure()); 103 104 if (tc.getIncludeAntRuntime()) { 105 task.log("Adding " + tc.getAntRuntimeClasses() 106 + " to CLASSPATH", 107 Project.MSG_VERBOSE); 108 cmd.createClasspath(project).createPath() 109 .append(tc.getAntRuntimeClasses()); 110 } 111 112 if (tc.getSummary()) { 113 task.log("Running " + qt.getName(), Project.MSG_INFO); 114 cmd.createArgument().setValue( 115 "formatter=org.quilt.reports.SummaryFormatter"); 116 } 117 118 cmd.createArgument().setValue("showoutput=" 119 + String.valueOf(qt.getShowOutput())); 120 121 StringBuffer formatterArg = new StringBuffer(256); 122 final FmtSelector[] selectors = tc.mergeSelectors(qt); 123 for (int i = 0; i < selectors.length; i++) { 124 FmtSelector fs = selectors[i]; 125 formatterArg.append("formatter="); 126 formatterArg.append(fs.getClassname()); 127 File outFile = tc.getOutput(fs, qt); 128 if (outFile != null) { 129 formatterArg.append(","); 130 formatterArg.append(outFile); 131 } 132 cmd.createArgument().setValue(formatterArg.toString()); 133 formatterArg.setLength(0); 134 } 135 136 File propsFile = 137 FileUtils.newFileUtils(). 138 createTempFile("quilt", ".properties", 139 project.getBaseDir()); 140 cmd.createArgument().setValue("propsfile=" 141 + propsFile.getAbsolutePath()); 142 Hashtable p = project.getProperties(); 143 Properties props = new Properties(); 144 for (Enumeration e = p.keys(); e.hasMoreElements(); ) { 145 Object key = e.nextElement(); 146 props.put(key, p.get(key)); 147 } 148 try { 149 FileOutputStream outstream = 150 new FileOutputStream(propsFile); 151 // props.save() is deprecated 152 props.save(outstream, 153 "Ant QuiltTask generated properties file"); 154 outstream.close(); 155 } catch (java.io.IOException e) { 156 propsFile.delete(); 157 throw new BuildException( 158 "Error creating temporary properties " 159 + "file.", e, task.getLocation()); 160 } 161 // prepare to fork the test 162 Execute forker = new Execute( 163 new LogStreamHandler(task, 164 Project.MSG_INFO, Project.MSG_WARN), watchdog); 165 forker.setCommandline(cmd.getCommandline()); 166 forker.setAntRun(project); 167 if (tc.getDir() != null) { 168 forker.setWorkingDirectory(tc.getDir()); 169 } 170 171 String[] environment = tc.getEnv().getVariables(); 172 if (environment != null) { 173 for (int i = 0; i < environment.length; i++) { 174 task.log("Setting environment variable: " + environment[i], 175 Project.MSG_VERBOSE); 176 } 177 } 178 forker.setNewenvironment(tc.getNewEnvironment()); 179 forker.setEnvironment(environment); 180 181 task.log(cmd.describeCommand(), Project.MSG_VERBOSE); 182 183 int retVal; 184 try { 185 retVal = forker.execute (); // do the actual fork 186 } catch (IOException e) { 187 throw new BuildException( 188 "Error forking test", e, task.getLocation()); 189 } finally { 190 if (watchdog != null && watchdog.killedProcess()) { 191 logTimeout(selectors, qt); 192 // see Bug 23150; also needs to be set to 1 if interrrupted 193 retVal = 1; 194 } 195 196 if (!propsFile.delete()) { 197 throw new BuildException( 198 "Error deleting temporary properties file."); 199 } 200 } 201 return retVal; 202 } 203 204 // DO WE REALLY WANT TO DO THIS, ONCE PER FORMATTER ? 205 206 private void logTimeout(FmtSelector[] selectors, 207 QuiltTest qt) { 208 209 for (int i = 0; i < selectors.length; i++) { 210 FmtSelector fs = selectors[i]; 211 File outFile = tc.getOutput(fs, qt); 212 Formatter formatter = fs.createFormatter(); 213 if (outFile != null && formatter != null) { 214 try { 215 OutputStream out = new FileOutputStream(outFile); 216 formatter.setOutput(out); 217 formatter.startTestSuite(qt); 218 qt.setCounts(0, 0, 1); 219 Test t = new Test() { 220 public int countTestCases() { return 0; } 221 public void run(TestResult r) { 222 throw new AssertionFailedError( 223 "Timeout during test run."); 224 } 225 }; 226 formatter.startTest(t); 227 formatter.addError(t, new AssertionFailedError( 228 "Timeout during test run.")); 229 230 formatter.endTestSuite(qt); 231 } catch (IOException e) { 232 // just ignore any more exceptions 233 } 234 } 235 } 236 } 237 }

This page was automatically generated by Maven