1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package bexee.ant;
19
20 import java.io.File;
21 import java.io.PrintStream;
22 import java.net.URL;
23
24 import junit.framework.TestCase;
25
26 import org.apache.tools.ant.BuildEvent;
27 import org.apache.tools.ant.BuildException;
28 import org.apache.tools.ant.BuildListener;
29 import org.apache.tools.ant.Project;
30 import org.apache.tools.ant.ProjectHelper;
31
32 /***
33 * A BuildFileTest is a TestCase which executes targets from an Ant buildfile
34 * for testing.
35 *
36 * This class provides a number of utility methods for particular build file
37 * tests which extend this class.
38 *
39 * @author Nico Seessle <nico@seessle.de>
40 * @author Conor MacNeill
41 */
42 public abstract class BuildFileTest extends TestCase {
43
44 protected Project project;
45
46 private StringBuffer logBuffer;
47 private StringBuffer fullLogBuffer;
48 private StringBuffer outBuffer;
49 private StringBuffer errBuffer;
50 private BuildException buildException;
51
52 /***
53 * Constructor for the BuildFileTest object
54 *
55 * @param name string to pass up to TestCase constructor
56 */
57 public BuildFileTest(String name) {
58 super(name);
59 }
60
61 /***
62 * run a target, expect for any build exception
63 *
64 *@param target target to run
65 *@param cause information string to reader of report
66 */
67 protected void expectBuildException(String target, String cause) {
68 expectSpecificBuildException(target, cause, null);
69 }
70
71 /***
72 * Assert that only the given message has been logged with a
73 * priority >= INFO when running the given target.
74 */
75 protected void expectLog(String target, String log) {
76 executeTarget(target);
77 String realLog = getLog();
78 assertEquals(log, realLog);
79 }
80
81 /***
82 * Assert that the given substring is in the log messages
83 */
84
85 protected void assertLogContaining(String substring) {
86 String realLog = getLog();
87 assertTrue("expecting log to contain \"" + substring + "\" log was \""
88 + realLog + "\"",
89 realLog.indexOf(substring) >= 0);
90 }
91
92 /***
93 * Assert that the given message has been logged with a priority
94 * >= INFO when running the given target.
95 */
96 protected void expectLogContaining(String target, String log) {
97 executeTarget(target);
98 assertLogContaining(log);
99 }
100
101 /***
102 * Gets the log the BuildFileTest object.
103 * only valid if configureProject() has
104 * been called.
105 * @pre logBuffer!=null
106 * @return The log value
107 */
108 protected String getLog() {
109 return logBuffer.toString();
110 }
111
112 /***
113 * Assert that the given message has been logged with a priority
114 * >= DEBUG when running the given target.
115 */
116 protected void expectDebuglog(String target, String log) {
117 executeTarget(target);
118 String realLog = getFullLog();
119 assertEquals(log, realLog);
120 }
121
122 /***
123 * Gets the log the BuildFileTest object.
124 * only valid if configureProject() has
125 * been called.
126 * @pre fullLogBuffer!=null
127 * @return The log value
128 */
129 protected String getFullLog() {
130 return fullLogBuffer.toString();
131 }
132
133 /***
134 * execute the target, verify output matches expectations
135 *
136 *@param target target to execute
137 *@param output output to look for
138 */
139
140 protected void expectOutput(String target, String output) {
141 executeTarget(target);
142 String realOutput = getOutput();
143 assertEquals(output, realOutput.trim());
144 }
145
146 /***
147 * execute the target, verify output matches expectations
148 * and that we got the named error at the end
149 *@param target target to execute
150 *@param output output to look for
151 *@param error Description of Parameter
152 */
153
154 protected void expectOutputAndError(String target, String output, String error) {
155 executeTarget(target);
156 String realOutput = getOutput();
157 assertEquals(output, realOutput);
158 String realError = getError();
159 assertEquals(error, realError);
160 }
161
162 protected String getOutput() {
163 return cleanBuffer(outBuffer);
164 }
165
166 protected String getError() {
167 return cleanBuffer(errBuffer);
168 }
169
170 protected BuildException getBuildException() {
171 return buildException;
172 }
173
174 private String cleanBuffer(StringBuffer buffer) {
175 StringBuffer cleanedBuffer = new StringBuffer();
176 boolean cr = false;
177 for (int i = 0; i < buffer.length(); i++) {
178 char ch = buffer.charAt(i);
179 if (ch == '\r') {
180 cr = true;
181 continue;
182 }
183
184 if (!cr) {
185 cleanedBuffer.append(ch);
186 } else {
187 cleanedBuffer.append(ch);
188 }
189 }
190 return cleanedBuffer.toString();
191 }
192
193 /***
194 * set up to run the named project
195 *
196 * @param filename name of project file to run
197 */
198 protected void configureProject(String filename) throws BuildException {
199 configureProject(filename, Project.MSG_DEBUG);
200 }
201
202 /***
203 * set up to run the named project
204 *
205 * @param filename name of project file to run
206 */
207 protected void configureProject(String filename, int logLevel)
208 throws BuildException {
209 logBuffer = new StringBuffer();
210 fullLogBuffer = new StringBuffer();
211 project = new Project();
212 project.init();
213 project.setUserProperty( "ant.file" , new File(filename).getAbsolutePath() );
214 project.addBuildListener(new AntTestListener(logLevel));
215 ProjectHelper helper = ProjectHelper.getProjectHelper();
216 project.addReference("ant.projectHelper", helper);
217 helper.parse(project, new File(filename));
218 }
219
220 /***
221 * execute a target we have set up
222 * @pre configureProject has been called
223 * @param targetName target to run
224 */
225 protected void executeTarget(String targetName) {
226 PrintStream sysOut = System.out;
227 PrintStream sysErr = System.err;
228 try {
229 sysOut.flush();
230 sysErr.flush();
231 outBuffer = new StringBuffer();
232 PrintStream out = new PrintStream(new AntOutputStream(outBuffer));
233 System.setOut(out);
234 errBuffer = new StringBuffer();
235 PrintStream err = new PrintStream(new AntOutputStream(errBuffer));
236 System.setErr(err);
237 logBuffer = new StringBuffer();
238 fullLogBuffer = new StringBuffer();
239 buildException = null;
240 project.executeTarget(targetName);
241 } finally {
242 System.setOut(sysOut);
243 System.setErr(sysErr);
244 }
245
246 }
247
248 /***
249 * Get the project which has been configured for a test.
250 *
251 * @return the Project instance for this test.
252 */
253 protected Project getProject() {
254 return project;
255 }
256
257 /***
258 * get the directory of the project
259 * @return the base dir of the project
260 */
261 protected File getProjectDir() {
262 return project.getBaseDir();
263 }
264
265 /***
266 * run a target, wait for a build exception
267 *
268 *@param target target to run
269 *@param cause information string to reader of report
270 *@param msg the message value of the build exception we are waiting for
271 set to null for any build exception to be valid
272 */
273 protected void expectSpecificBuildException(String target, String cause, String msg) {
274 try {
275 executeTarget(target);
276 } catch (org.apache.tools.ant.BuildException ex) {
277 buildException = ex;
278 if ((null != msg) && (!ex.getMessage().equals(msg))) {
279 fail("Should throw BuildException because '" + cause
280 + "' with message '" + msg
281 + "' (actual message '" + ex.getMessage() + "' instead)");
282 }
283 return;
284 }
285 fail("Should throw BuildException because: " + cause);
286 }
287
288 /***
289 * run a target, expect an exception string
290 * containing the substring we look for (case sensitive match)
291 *
292 *@param target target to run
293 *@param cause information string to reader of report
294 *@param contains substring of the build exception to look for
295 */
296 protected void expectBuildExceptionContaining(String target, String cause, String contains) {
297 try {
298 executeTarget(target);
299 } catch (org.apache.tools.ant.BuildException ex) {
300 buildException = ex;
301 if ((null != contains) && (ex.getMessage().indexOf(contains) == -1)) {
302 fail("Should throw BuildException because '" + cause + "' with message containing '" + contains + "' (actual message '" + ex.getMessage() + "' instead)");
303 }
304 return;
305 }
306 fail("Should throw BuildException because: " + cause);
307 }
308
309
310 /***
311 * call a target, verify property is as expected
312 *
313 * @param target build file target
314 * @param property property name
315 * @param value expected value
316 */
317
318 protected void expectPropertySet(String target, String property, String value) {
319 executeTarget(target);
320 assertPropertyEquals(property, value);
321 }
322
323 /***
324 * assert that a property equals a value; comparison is case sensitive.
325 * @param property property name
326 * @param value expected value
327 */
328 protected void assertPropertyEquals(String property, String value) {
329 String result = project.getProperty(property);
330 assertEquals("property " + property,value,result);
331 }
332
333 /***
334 * assert that a property equals "true"
335 * @param property property name
336 */
337 protected void assertPropertySet(String property) {
338 assertPropertyEquals(property, "true");
339 }
340
341 /***
342 * assert that a property is null
343 * @param property property name
344 */
345 protected void assertPropertyUnset(String property) {
346 assertPropertyEquals(property, null);
347 }
348
349
350 /***
351 * call a target, verify named property is "true".
352 *
353 * @param target build file target
354 * @param property property name
355 */
356 protected void expectPropertySet(String target, String property) {
357 expectPropertySet(target, property, "true");
358 }
359
360
361 /***
362 * call a target, verify property is null
363 * @param target build file target
364 * @param property property name
365 */
366 protected void expectPropertyUnset(String target, String property) {
367 expectPropertySet(target, property, null);
368 }
369
370 /***
371 * Retrieve a resource from the caller classloader to avoid
372 * assuming a vm working directory. The resource path must be
373 * relative to the package name or absolute from the root path.
374 * @param resource the resource to retrieve its url.
375 * @throws AssertionFailureException if resource is not found.
376 */
377 protected URL getResource(String resource){
378 URL url = getClass().getResource(resource);
379 assertNotNull("Could not find resource :" + resource, url);
380 return url;
381 }
382
383 /***
384 * an output stream which saves stuff to our buffer.
385 */
386 private static class AntOutputStream extends java.io.OutputStream {
387 private StringBuffer buffer;
388
389 public AntOutputStream( StringBuffer buffer ) {
390 this.buffer = buffer;
391 }
392
393 public void write(int b) {
394 buffer.append((char)b);
395 }
396 }
397
398 /***
399 * our own personal build listener
400 */
401 private class AntTestListener implements BuildListener {
402 private int logLevel;
403
404 /***
405 * Constructs a test listener which will ignore log events
406 * above the given level
407 */
408 public AntTestListener(int logLevel) {
409 this.logLevel = logLevel;
410 }
411
412 /***
413 * Fired before any targets are started.
414 */
415 public void buildStarted(BuildEvent event) {
416 }
417
418 /***
419 * Fired after the last target has finished. This event
420 * will still be thrown if an error occured during the build.
421 *
422 * @see BuildEvent#getException()
423 */
424 public void buildFinished(BuildEvent event) {
425 }
426
427 /***
428 * Fired when a target is started.
429 *
430 * @see BuildEvent#getTarget()
431 */
432 public void targetStarted(BuildEvent event) {
433
434 }
435
436 /***
437 * Fired when a target has finished. This event will
438 * still be thrown if an error occured during the build.
439 *
440 * @see BuildEvent#getException()
441 */
442 public void targetFinished(BuildEvent event) {
443
444 }
445
446 /***
447 * Fired when a task is started.
448 *
449 * @see BuildEvent#getTask()
450 */
451 public void taskStarted(BuildEvent event) {
452
453 }
454
455 /***
456 * Fired when a task has finished. This event will still
457 * be throw if an error occured during the build.
458 *
459 * @see BuildEvent#getException()
460 */
461 public void taskFinished(BuildEvent event) {
462
463 }
464
465 /***
466 * Fired whenever a message is logged.
467 *
468 * @see BuildEvent#getMessage()
469 * @see BuildEvent#getPriority()
470 */
471 public void messageLogged(BuildEvent event) {
472 if (event.getPriority() > logLevel) {
473
474 return;
475 }
476
477 if (event.getPriority() == Project.MSG_INFO ||
478 event.getPriority() == Project.MSG_WARN ||
479 event.getPriority() == Project.MSG_ERR) {
480 logBuffer.append(event.getMessage());
481 }
482 fullLogBuffer.append(event.getMessage());
483
484 }
485 }
486
487
488 }