View Javadoc
1 /* QuiltTask.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.optional.junit.Enumerations; 9 import org.apache.tools.ant.types.Commandline; 10 import org.apache.tools.ant.types.CommandlineJava; 11 import org.apache.tools.ant.types.Environment; 12 import org.apache.tools.ant.types.Path; 13 14 import java.io.File; 15 import java.net.URL; 16 import java.util.Enumeration; 17 import java.util.Vector; 18 19 import org.quilt.cl.QuiltClassLoader; 20 import org.quilt.framework.QuiltTest; 21 import org.quilt.reports.FmtSelector; 22 import org.quilt.cover.stmt.StmtRegistry; 23 //import org.quilt.runner.*; 24 25 /*** 26 * Ant task for running Quilt and JUnit. 27 * 28 * <p>The Quilt Ant task is meant to be a plug-in replacement for 29 * the Ant JUnitTask. Whatever build.xml works with JUnitTask 30 * should behave identically with QuiltTask. The opposite is not 31 * true: using QuiltTask allows you to run coverage tests in 32 * addition to JUnit unit tests</p> 33 * 34 * <p>Parameter names / build file options are compatible with 35 * the build.xml options for JUnitTask as of Ant 1.5.3-1, so that 36 * if <junit> and </junit> are replaced with <quilt> and </quilt> 37 * respectively in the build.xml file, test behavior should be the same.</p> 38 * 39 * <p>Build file options either control the individual test and so 40 * are passed to Quilt and JUnit, or manage QuiltTask and the test 41 * process.</p> 42 * 43 * <p>Most test options will go through Quilt to JUnit. 44 * All are set by Ant set* methods, where the name for the method 45 * setting the variable 'var' is 'setVar'. That is, the first 46 * letter of the variable name is capitalized, then the modified 47 * name is appended to 'set'.</p> 48 * 49 * <p>Task control parameters are NOT passed through to Quilt or JUnit. 50 * These variables are modified by Ant add*, set*, and create* routines, where 51 * the names are determined as described above.</p> 52 * 53 * <p>QuiltTest options can be set at three levels. First, then can 54 * be set as attributes to the <quilt&gr; element. In this case, 55 * they are the defaults for all tests.</p> 56 * 57 * <p>Next, they can be set at the <batchtest> leve.. In this case, 58 * these attributes will be used for all files in the batch test.</p> 59 * 60 * <p>Finally, they can be set at the <test> level, in which case 61 * they will override the defaults set higher up.</p> 62 * 63 * <p>QuiltTask collects filesets from batch test elements and the 64 * names of individual tests. These are then passed to a Scheduler 65 * which unpacks the batch tests and schedules all tests for running.</p> 66 * 67 * <p>It may be important to understand that under certain circumstances 68 * batches of tests will be run more than once result. This will normally 69 * be the result of an error in the way that dependencies are structured 70 * in build.xml. </p> 71 * 72 * @see QuiltTest 73 * @see Scheduler 74 * @see TaskControl 75 */ 76 public class QuiltTask extends Task { 77 private Scheduler sch = null; 78 private TaskControl tc = null; 79 80 // // THESE DUPLICATE ELEMENTS OF TaskControl ////////////////// 81 // // XXX and this apparently isn't set -- leading to bugs 82 // private CommandlineJava commandline = new CommandlineJava(); 83 84 // DO THESE BELONG IN TaskControl ? 85 private boolean includeAntRuntime = true; 86 private Path antRuntimeClasses = null; 87 88 // COLLECT ANT PARAMETERS USING ADD/CREATE/SET ////////////////// 89 // Please keep in order by variable name //////////////////////// 90 91 // TEST PARAMETERS ////////////////////////////////////////////// 92 // Ant creates child elements (individual tests and BatchTests), 93 // then assigns values to task attributes, and THEN assigns 94 // values to child element attributes. This means that the 95 // default values assigned at the task level can be overridden 96 // by test and batch level assignments, IF the task-level values 97 // are applied immediately to all tests and batch tests. 98 // 99 // The methods that follow assign such task-level defaults. It 100 // is important to bear in mind that Ant uses methods of the same 101 // name and call QuiltTask to assign defaults and to call 102 // QuiltTest and BatchTest to override these defaults. 103 // ////////////////////////////////////////////////////////////// 104 private QuiltTest qt // scratch variable 105 = new QuiltTest(); // to keep the compiler quiet 106 public void setCheckCoverage (boolean b) { 107 sch.schedule(); 108 while ( (qt = sch.nextTest()) != null) { 109 qt.setCheckCoverage(b); 110 } 111 } 112 public void setCheckExcludes (String s) { 113 sch.schedule(); 114 while ( (qt = sch.nextTest()) != null) { 115 qt.setCheckExcludes(s); 116 } 117 } 118 public void setCheckIncludes (String s) { 119 sch.schedule(); 120 while ( (qt = sch.nextTest()) != null) { 121 qt.setCheckIncludes(s); 122 } 123 } 124 public void setErrorProperty(String propertyName) { 125 sch.schedule(); 126 while ( (qt = sch.nextTest()) != null) { 127 qt.setErrorProperty(propertyName); 128 } 129 } 130 public void setFailureProperty(String propertyName) { 131 sch.schedule(); 132 while ( (qt = sch.nextTest()) != null) { 133 qt.setFailureProperty(propertyName); 134 } 135 } 136 public void setFiltertrace(boolean b) { 137 sch.schedule(); 138 while ( (qt = sch.nextTest()) != null) { 139 qt.setFiltertrace(b); 140 } 141 } 142 public void setFork(boolean b) { 143 sch.schedule(); 144 while ( (qt = sch.nextTest()) != null) { 145 qt.setFork(b); 146 } 147 } 148 public void setHaltOnError(boolean b) { 149 sch.schedule(); 150 while ( (qt = sch.nextTest()) != null) { 151 qt.setHaltOnError(b); 152 } 153 } 154 public void setHaltOnFailure(boolean b) { 155 sch.schedule(); 156 while ( (qt = sch.nextTest()) != null) { 157 qt.setHaltOnFailure(b); 158 } 159 } 160 public void setMockTestRun(boolean b) { 161 sch.schedule(); 162 while ( (qt = sch.nextTest()) != null) { 163 qt.setMockTestRun (b); 164 } 165 } 166 public void setShowOutput(boolean b) { 167 tc.setShowOutput(b); // NEEDS FIXING 168 sch.schedule(); 169 while ( (qt = sch.nextTest()) != null) { 170 qt.setShowOutput(b); 171 } 172 } 173 174 // TASK PARAMETERS ////////////////////////////////////////////// 175 // ////////////////////////////////////////////////////////////// 176 177 public BatchTest createBatchTest () { 178 BatchTest bt = new BatchTest (getProject()); 179 sch.addBatchTest(bt); 180 return bt; // returns to Ant a reference to the object created 181 } 182 183 public Path createClasspath() { 184 // commandline.createClasspath(getProject()).createPath(); // XXX 185 return tc.createClasspath(); 186 } 187 public void setDir(File dir) { 188 tc.setDir(dir); 189 } 190 public void addEnv(Environment.Variable var) { 191 tc.addEnv(var); 192 } 193 public void addFormatter(FmtSelector fe) { 194 tc.addFormatter(fe); 195 } 196 public void setIncludeAntRuntime(boolean b) { 197 tc.setIncludeAntRuntime(b); 198 } 199 public void setJvm(String value) { 200 tc.setJvm(value); 201 } 202 public Commandline.Argument createJvmarg() { 203 return tc.createJvmarg(); 204 } 205 public void setMaxmemory(String max) { 206 tc.setMaxmemory (max); 207 } 208 public void setMockExec(boolean b) { 209 tc.setMockExec(b); 210 } 211 public void setNewenvironment(boolean b) { 212 tc.setNewEnvironment(b); 213 } 214 // compatible with JUnitTask but kludgey 215 public void setPrintsummary(String sValue) { 216 SummaryAttribute sa = new SummaryAttribute(sValue); 217 tc.setSummary (sa.asBoolean()); 218 tc.setSummaryValue (sa.getValue()); 219 } 220 public void addSysproperty(Environment.Variable sysp) { 221 tc.addSysproperty(sysp); 222 } 223 public void addTest(QuiltTest qt) { 224 sch.addTest (qt); 225 } 226 public void setTimeout(Long t) { 227 tc.setTimeout (t); 228 } 229 230 // CONSTRUCTOR ////////////////////////////////////////////////// 231 public QuiltTask() throws Exception { 232 sch = new Scheduler (this); 233 tc = sch.getTaskControl(); 234 } 235 236 private MockExec mockE = null; 237 private TestExec testE = null; 238 private boolean mockery = false; 239 240 private boolean firstTimeThrough = true; 241 private void addCPEs () { 242 mockery = tc.getMockExec(); 243 if (mockery) { 244 mockE = new MockExec(); 245 } else { 246 testE = new TestExec(); 247 } 248 addClasspathEntry("/junit/framework/TestCase.class"); 249 addClasspathEntry("/org/apache/tools/ant/Task.class"); 250 addClasspathEntry("/org/quilt/runner/BaseTestRunner.class"); 251 } 252 // FIRST ANT ENTRY POINT: init() //////////////////////////////// 253 // only called once ///////////////////////////////////////////// 254 public void init() { 255 antRuntimeClasses = new Path(getProject()); 256 } 257 258 // SECOND ANT ENTRY POINT: execute () /////////////////////////// 259 // May be called many times ///////////////////////////////////// 260 public void execute() throws BuildException { 261 if (firstTimeThrough) { 262 firstTimeThrough = false; 263 addCPEs(); 264 sch.unbatch(); // merge batch tests with other tests 265 } 266 sch.schedule(); 267 268 Path quiltClassPath = tc.getCommandline().getClasspath(); 269 if (tc.getIncludeAntRuntime()) { 270 quiltClassPath.append ( tc.getAntRuntimeClasses() ); 271 } 272 QuiltClassLoader qcl = new QuiltClassLoader ( 273 QuiltClassLoader.cpToURLs( 274 tc.getCommandline().getClasspath().toString()), 275 this.getClass().getClassLoader(), // we delegate to .. 276 // delegated included excluded 277 (String[])null, (String[])null, (String[])null); 278 StmtRegistry stmtReg = (StmtRegistry)qcl.addQuiltRegistry( 279 "org.quilt.cover.stmt.StmtRegistry" ); 280 if (stmtReg == null) { 281 System.out.println( 282 "QuiltTask.execute: org.quilt.cover.stmt.StmtRegistry not found\n" 283 + " classpath error?"); 284 } 285 tc.setLoader(qcl); 286 while ( (qt = sch.nextTest()) != null) { 287 if (tc.getMockExec()) { 288 mockE.run(qt, tc); 289 } else if (qt.runMe (getProject())) { 290 testE.execute(qt, tc); 291 } 292 } 293 if (stmtReg != null) { 294 System.out.println ( 295 stmtReg.getReport() 296 ); 297 } 298 // DEBUG 299 else System.out.println( 300 "QuiltTask.execute: after running tests, stmtReg is null"); 301 // END 302 } 303 304 // ////////////////////////////////////////////////////////////// 305 // CLEAN ME UP. This code is per JUnit task, needs work. 306 // ////////////////////////////////////////////////////////////// 307 308 protected void addClasspathEntry(String resource) { 309 URL url = getClass().getResource(resource); 310 if (url != null) { 311 String u = url.toString(); 312 if (u.startsWith("jar:file:")) { 313 int pling = u.indexOf("!"); // Ant standard term 314 String jarName = u.substring(9, pling); 315 log("Found " + jarName, Project.MSG_DEBUG); 316 antRuntimeClasses.createPath() 317 .setLocation(new File((new File(jarName)) 318 .getAbsolutePath())); 319 } else if (u.startsWith("file:")) { 320 int tail = u.indexOf(resource); 321 String dirName = u.substring(5, tail); 322 log("Found " + dirName, Project.MSG_DEBUG); 323 antRuntimeClasses.createPath() 324 .setLocation(new File((new File(dirName)) 325 .getAbsolutePath())); 326 } else { 327 log("Don\'t know how to handle resource URL " + u, 328 Project.MSG_DEBUG); 329 } 330 } else { 331 log("Couldn\'t find " + resource, Project.MSG_DEBUG); 332 } 333 } 334 // TASK CONTROL SUPPORT ////////////////////////////////////////// 335 public void handleTheOutput(String line) { 336 super.handleOutput(line); 337 } 338 public void handleTheFlush(String line) { 339 super.handleFlush(line); 340 } 341 public void handleTheErrorOutput(String line) { 342 super.handleErrorOutput(line); 343 } 344 public void handleTheErrorFlush(String line) { 345 super.handleErrorFlush(line); 346 } 347 }

This page was automatically generated by Maven