You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AntTaskTester.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /* *******************************************************************
  2. * Copyright (c) 1999-2001 Xerox Corporation,
  3. * 2002 Palo Alto Research Center, Incorporated (PARC).
  4. * All rights reserved.
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Common Public License v1.0
  7. * which accompanies this distribution and is available at
  8. * http://www.eclipse.org/legal/cpl-v10.html
  9. *
  10. * Contributors:
  11. * Xerox/PARC initial implementation
  12. * ******************************************************************/
  13. import org.apache.tools.ant.*;
  14. import java.io.*;
  15. import java.lang.reflect.*;
  16. import java.util.*;
  17. /**
  18. * Provides utility methods to test ant tasks.
  19. */
  20. public abstract class AntTaskTester implements BuildListener {
  21. public abstract String getAntFile();
  22. protected PrintStream out = System.out;
  23. protected PrintStream err = System.err;
  24. protected void info(Object msg) {
  25. out.println(" [" + msg + "]");
  26. }
  27. protected Project project;
  28. protected String taskname = "unset";
  29. protected List errors = new Vector();
  30. protected void throwable(Throwable t) {
  31. error(taskname, t);
  32. t.printStackTrace();
  33. }
  34. protected void error(String task, Object msg) {
  35. error("[" + task + "]: " + msg);
  36. }
  37. protected void error(Object msg) {
  38. err.println("Error: " + msg);
  39. errors.add(msg);
  40. }
  41. protected List wants = new Vector();
  42. protected void want(Object object) {
  43. wants.add(object);
  44. }
  45. protected List haves = new Vector();
  46. protected void have(Object object) {
  47. haves.add(object);
  48. }
  49. protected List donts = new Vector();
  50. protected void dont(Object object) {
  51. donts.add(object);
  52. }
  53. protected void clear() {
  54. wants = new Vector();
  55. haves = new Vector();
  56. donts = new Vector();
  57. }
  58. protected final boolean verbose = verbose();
  59. protected boolean verbose() { return false; }
  60. protected void log(String msg) {
  61. if (verbose) out.println("[ " + msg + " ]");
  62. }
  63. public void printSummary() {
  64. Iterator iter = errors.iterator();
  65. out.println();
  66. out.println("----------------------- Test Summary -----------------------");
  67. if (errors.size() == 0) {
  68. out.println("no errors");
  69. } else {
  70. out.println(errors.size() + " error" + (errors.size() > 1 ? "s" : ""));
  71. while (iter.hasNext()) {
  72. out.println(" " + iter.next());
  73. }
  74. }
  75. out.println("------------------------------------------------------------");
  76. }
  77. /**
  78. * Checks the all the assertions we wanted were achieved
  79. * and all those received were desired.
  80. */
  81. protected void checkAfterTask() {
  82. log("checking after task");
  83. for (Iterator i = wants.iterator(); i.hasNext();) {
  84. Object want = i.next();
  85. check(haves.contains(want),
  86. "didn't see " + want + " in " + haves);
  87. }
  88. for (Iterator i = haves.iterator(); i.hasNext();) {
  89. Object have = i.next();
  90. check(wants.contains(have),
  91. "shouldn't have seen " + have + " in " + wants);
  92. }
  93. for (Iterator i = donts.iterator(); i.hasNext();) {
  94. Object dont = i.next();
  95. check(!haves.contains(dont),
  96. "should't have seen " + dont + " in " + haves);
  97. }
  98. }
  99. /**
  100. * Logs an error in <code>!b</code> with message <code>msg</code>.
  101. *
  102. * @param b <code>true</code> for an error.
  103. * @param msg Failure message.
  104. */
  105. protected void check(boolean b, String msg) {
  106. if (!b) error(taskname, msg);
  107. }
  108. /**
  109. * Calls {@link #check(boolean,String)} with the result
  110. * of comparing equality of <code>o1</code> and <code>o2</code>,
  111. * failing with message <code>msg</code>.
  112. *
  113. * @param o1 First comparison.
  114. * @param o2 Other comparison.
  115. * @param msg Failure message.
  116. */
  117. protected void check(Object o1, Object o2, String msg) {
  118. if (o1 != null) {
  119. check(o1.equals(o2), msg);
  120. } else if (o2 != null) {
  121. check(o2.equals(o1), msg);
  122. } else {
  123. check(true, msg);
  124. }
  125. }
  126. /**
  127. * Calls {@link #runProject} with <code>args</code> and
  128. * the result of {@link #getAntFile}.
  129. *
  130. * @param args Arguments given on the command line.
  131. * @see #runProject(String[], String)
  132. */
  133. public void runTests(String[] args) {
  134. runProject(args, getAntFile());
  135. }
  136. /**
  137. * Loads the project, collects a list of methods, and
  138. * passes these methods to {@link #runProject(Method[])}.
  139. *
  140. * @param args Command line arguments.
  141. * @param buildFile XML file that we are giving to ANT.
  142. * @see #runProject(Method[])
  143. */
  144. public void runProject(String[] args, String buildFile) {
  145. loadProject(buildFile);
  146. Method[] methods = null;
  147. if (args == null || args.length == 0 || args[0].equals("${args}")) {
  148. methods = getClass().getMethods();
  149. } else {
  150. methods = new Method[args.length];
  151. for (int i = 0; i < args.length; i++) {
  152. String name = args[i];
  153. if (!Character.isJavaIdentifierStart(name.charAt(0)) || // todo wes: was (i)?
  154. name.charAt(0) == '$') {
  155. continue;
  156. }
  157. try {
  158. methods[i] = getClass().getMethod(name, new Class[]{});
  159. } catch (NoSuchMethodException nsme) {
  160. methods[i] = null;
  161. }
  162. }
  163. }
  164. runProject(methods);
  165. }
  166. /**
  167. * Execute the targets whose name matches those found in <code>methods</code>.
  168. *
  169. * @param methods List of methods to execute.
  170. */
  171. protected final void runProject(Method[] methods) {
  172. if (methods == null || methods.length < 1) {
  173. return;
  174. }
  175. for (int i = 0; i < methods.length; i++) {
  176. Method method = methods[i];
  177. if (method == null) {
  178. error("a method is null!");
  179. continue;
  180. }
  181. taskname = method.getName();
  182. if (taskname.startsWith("test")) {
  183. info("test task: " + taskname);
  184. try {
  185. method.invoke(this, new Object[]{});
  186. beforeTasks();
  187. execute(taskname);
  188. afterTasks();
  189. } catch (Throwable t) {
  190. throwable(t);
  191. } finally {
  192. info("done task: " + taskname);
  193. }
  194. } else if (taskname.startsWith("fail")) {
  195. info("fail task: " + taskname);
  196. try {
  197. beforeTasks();
  198. want(taskname + "-error");
  199. execute(taskname);
  200. afterTasks();
  201. } catch (Throwable t) {
  202. if (t instanceof BuildException) {
  203. have(taskname + "-error");
  204. try {
  205. method.invoke(this, new Object[]{t});
  206. } catch (Throwable tt) {
  207. throwable(tt);
  208. }
  209. } else {
  210. throwable(t);
  211. }
  212. } finally {
  213. info("done task: " + taskname);
  214. }
  215. }
  216. }
  217. printSummary();
  218. }
  219. /**
  220. * Called before every task.
  221. */
  222. private final void beforeTasks() {
  223. clear();
  224. beforeMethod();
  225. beforeEveryTask();
  226. }
  227. /**
  228. * Called after every task.
  229. */
  230. private final void afterTasks() {
  231. afterMethod();
  232. afterEveryTask();
  233. checkAfterTask();
  234. }
  235. /**
  236. * Invokes the method with prefix <code>prefix</code>.
  237. *
  238. * @param prefix Prefix of the method to execute.
  239. */
  240. private final void taskMethod(String prefix) {
  241. String name = prefix + Character.toUpperCase(taskname.charAt(0)) +
  242. taskname.substring(1);
  243. try {
  244. Method method = getClass().getDeclaredMethod(name, new Class[]{});
  245. if (method != null) {
  246. method.invoke(this, new Object[]{});
  247. }
  248. } catch (Throwable t) {
  249. }
  250. }
  251. /**
  252. * Executes the method with prefix <code>after</code>.
  253. */
  254. private final void afterMethod() {
  255. taskMethod("after");
  256. }
  257. /**
  258. * Executes the method with prefix <code>before</code>.
  259. */
  260. private final void beforeMethod() {
  261. taskMethod("before");
  262. }
  263. /**
  264. * Override this to do some work before every task.
  265. */
  266. protected void beforeEveryTask() {}
  267. /**
  268. * Override this for initialization -- called at
  269. * the end of {@link #loadProject}.
  270. */
  271. protected void init() {}
  272. /**
  273. * Override this to do some work after every task.
  274. */
  275. protected void afterEveryTask() {}
  276. protected void setProperties(Map map, boolean user) {
  277. Iterator iter = map.keySet().iterator();
  278. while (iter.hasNext()) {
  279. Object key = iter.next();
  280. Object val = map.get(key);
  281. String keyString = key + "";
  282. String valString = val + "";
  283. if (user) {
  284. project.setUserProperty(keyString, valString);
  285. } else {
  286. project.setProperty(keyString, valString);
  287. }
  288. }
  289. }
  290. protected void setProperties() {
  291. setProperties(getProperties(), false);
  292. }
  293. protected void setUserProperties() {
  294. setProperties(getUserProperties(), true);
  295. }
  296. /**
  297. * Override this to provide user properties -- default to
  298. * an empty <code>HashMap</code>.
  299. *
  300. * @return Empty <code>HashMap</code>.
  301. */
  302. protected Map getUserProperties() {
  303. return new HashMap();
  304. }
  305. /**
  306. * Override this to provide system properties -- default to
  307. * an empty <code>HashMap</code>.
  308. *
  309. * @return Empty <code>HashMap</code>.
  310. */
  311. protected Map getProperties() {
  312. return new HashMap();
  313. }
  314. /**
  315. * Loads the project with file name <code>buildFile</code>.
  316. *
  317. * @param buildFile Name of the XML file to load.
  318. */
  319. public void loadProject(String buildFile) {
  320. project = new Project();
  321. project.init();
  322. project.setUserProperty("ant.file", new File(buildFile).getAbsolutePath() );
  323. setProperties();
  324. setUserProperties();
  325. project.addBuildListener(this);
  326. ProjectHelper.configureProject(project, new File(buildFile));
  327. init();
  328. }
  329. public void execute(String targetName) {
  330. try {
  331. project.executeTarget(targetName);
  332. } finally {
  333. }
  334. }
  335. private static class StringBufferOutputStream extends OutputStream {
  336. private StringBuffer buf;
  337. public StringBufferOutputStream(StringBuffer buf) {
  338. this.buf = buf;
  339. }
  340. public void write(int c) {
  341. buf.append((char)c);
  342. }
  343. }
  344. public boolean verbosity(BuildEvent event) {
  345. int[] verbosities = verbosities();
  346. int priority = event.getPriority();
  347. for (int i = 0; i < verbosities.length; i++) {
  348. if (priority == verbosities[i]) return true;
  349. }
  350. return false;
  351. }
  352. public int[] verbosities() {
  353. return new int[] { /*Project.MSG_VERBOSE,*/ Project.MSG_INFO, Project.MSG_WARN, project.MSG_ERR };
  354. }
  355. // BuildListener
  356. public void buildFinished(BuildEvent event) {
  357. }
  358. public void buildStarted(BuildEvent event) {
  359. }
  360. public void messageLogged(BuildEvent event) {
  361. if (verbosity(event)) {
  362. out.println(event.getMessage());
  363. }
  364. }
  365. public void targetFinished(BuildEvent event) {
  366. }
  367. public void targetStarted(BuildEvent event) {
  368. }
  369. public void taskFinished(BuildEvent event) {
  370. }
  371. public void taskStarted(BuildEvent event) {
  372. }
  373. }