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.

AjcTaskTest.java 37KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
  1. /* *******************************************************************
  2. * Copyright (c) 1999-2001 Xerox Corporation,
  3. * 2002 Palo Alto Research Center, Incorporated (PARC)
  4. * 2003 Contributors.
  5. * 2005 Contributors
  6. * All rights reserved.
  7. * This program and the accompanying materials are made available
  8. * under the terms of the Eclipse Public License v 2.0
  9. * which accompanies this distribution and is available at
  10. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  11. *
  12. * Contributors:
  13. * Xerox/PARC initial implementation
  14. * IBM ongoing maintenance
  15. * ******************************************************************/
  16. package org.aspectj.tools.ant.taskdefs;
  17. import java.io.BufferedReader;
  18. import java.io.File;
  19. import java.io.FileFilter;
  20. import java.io.FileReader;
  21. import java.io.IOException;
  22. import java.io.PrintStream;
  23. import java.util.ArrayList;
  24. import java.util.Arrays;
  25. import java.util.jar.JarEntry;
  26. import java.util.jar.JarFile;
  27. import org.apache.tools.ant.BuildEvent;
  28. import org.apache.tools.ant.BuildException;
  29. import org.apache.tools.ant.BuildListener;
  30. import org.apache.tools.ant.Location;
  31. import org.apache.tools.ant.Project;
  32. import org.apache.tools.ant.types.Path;
  33. import org.apache.tools.ant.types.selectors.FilenameSelector;
  34. import org.aspectj.bridge.IMessage;
  35. import org.aspectj.bridge.IMessageHolder;
  36. import org.aspectj.bridge.MessageHandler;
  37. import org.aspectj.bridge.MessageUtil;
  38. import org.aspectj.tools.ant.taskdefs.AjcTask.CompilerArg;
  39. import org.aspectj.util.FileUtil;
  40. import org.aspectj.util.LangUtil;
  41. import junit.framework.TestCase;
  42. /**
  43. * AjcTask test cases.
  44. * Please put new ones with others between ------- comments.
  45. *
  46. * Some API tests, but mostly functional tests driving
  47. * the task execute using data in ../taskdefs/testdata.
  48. * This will re-run in forked mode for any nonfailing
  49. * compile if aspectjtools-dist is built into
  50. * ../aj-build/dist/tools/lib/aspectjtools.jar.
  51. */
  52. public class AjcTaskTest extends TestCase {
  53. private static final Class NO_EXCEPTION = null;
  54. private static final String NOFILE = "NOFILE";
  55. private static final File tempDir;
  56. private static final String aspectjtoolsJar;
  57. private static final String testdataDir;
  58. private static final StringBuffer MESSAGES = new StringBuffer();
  59. /** accept writable .class files */
  60. private static FileFilter PICK_CLASS_FILES;
  61. static {
  62. tempDir = new File("IncrementalAjcTaskTest-temp");
  63. String toolsPath = "../aj-build/dist/tools/lib/aspectjtools.jar";
  64. File toolsjar = new File(toolsPath);
  65. if (toolsjar.canRead()) {
  66. aspectjtoolsJar = toolsjar.getAbsolutePath();
  67. } else {
  68. aspectjtoolsJar = null;
  69. String s =
  70. "AjcTaskTest not forking - build aspectjtools-dist to get "
  71. + toolsPath;
  72. System.out.println(s);
  73. }
  74. File dir = new File("../taskdefs/testdata");
  75. if (dir.canRead() && dir.isDirectory()) {
  76. testdataDir = dir.getAbsolutePath();
  77. } else {
  78. testdataDir = null;
  79. }
  80. PICK_CLASS_FILES = new FileFilter() {
  81. @Override
  82. public boolean accept(File file) {
  83. return (
  84. (null != file)
  85. && file.isFile()
  86. && file.canWrite()
  87. && file.getPath().endsWith(".class"));
  88. }
  89. };
  90. }
  91. /**
  92. * Check that aspectjtools are found on the classpath,
  93. * reporting any errors to System.err.
  94. *
  95. * Run multiple times with different classpaths.
  96. * This should find variants
  97. * aspectjtools.jar,
  98. * aspectj-tools.jar,
  99. * aspectj-tools-1.1.jar, and
  100. * aspectjtools-1.0.6.jar
  101. * but not
  102. * aspectjrt.jar or
  103. * aspectj/tools.jar.
  104. * XXX use testing aspect to stub out
  105. * <code>System.getProperty("java.class.path")</code>
  106. * @param args a String[], first is expected path, if any
  107. */
  108. public static void main(String[] args) {
  109. java.io.File toolsjar = AjcTask.findAspectjtoolsJar();
  110. if ((null == args) || (0 == args.length)) {
  111. if (null != toolsjar) {
  112. System.err.println("FAIL - not expected: " + toolsjar);
  113. }
  114. } else if ("-help".equals(args[0])) {
  115. System.out.println(
  116. "java "
  117. + AjcTaskTest.class.getName()
  118. + " <expectedPathToAspectjtoolsJar>");
  119. } else if (null == toolsjar) {
  120. System.err.println("FAIL - expected: " + args[0]);
  121. } else {
  122. String path = toolsjar.getAbsolutePath();
  123. if (!path.equals(args[0])) {
  124. System.err.println(
  125. "FAIL - expected: " + args[0] + " actual: " + path);
  126. }
  127. }
  128. }
  129. public static void collectMessage(String s) {
  130. MESSAGES.append(s);
  131. }
  132. private static void deleteTempDir() {
  133. if ((null != tempDir) && tempDir.exists()) {
  134. FileUtil.deleteContents(tempDir);
  135. tempDir.delete();
  136. // when tempDir not used...
  137. if (null != testdataDir) {
  138. File dataDir = new File(testdataDir);
  139. if (dataDir.canRead()) {
  140. FileUtil.deleteContents(dataDir, PICK_CLASS_FILES, false);
  141. }
  142. }
  143. }
  144. }
  145. private static final File getTempDir() {
  146. return tempDir;
  147. }
  148. public AjcTaskTest(String name) {
  149. super(name);
  150. }
  151. @Override
  152. public void tearDown() {
  153. deleteTempDir();
  154. MESSAGES.setLength(0);
  155. }
  156. private void checkRun(AjcTask task, String exceptionString) {
  157. try {
  158. task.execute();
  159. assertTrue(null == exceptionString);
  160. } catch (BuildException e) {
  161. if (null == exceptionString) {
  162. assertTrue("unexpected " + e.getMessage(), false);
  163. } else {
  164. String m = e.getMessage();
  165. if (null == m) {
  166. assertTrue("not " + exceptionString, false);
  167. } else if (!m.contains(exceptionString)) {
  168. assertEquals(exceptionString, e.getMessage());
  169. }
  170. }
  171. }
  172. }
  173. private void checkContains(String[] cmd, String option, boolean contains) {
  174. for (String s : cmd) {
  175. if (option.equals(s)) {
  176. if (contains) {
  177. return;
  178. } else {
  179. assertTrue(
  180. "not expecting " + option + " in " + Arrays.asList(cmd),
  181. false);
  182. }
  183. }
  184. }
  185. if (contains) {
  186. assertTrue(
  187. "expecting " + option + " in " + Arrays.asList(cmd),
  188. false);
  189. }
  190. }
  191. protected AjcTask getTask(String input) {
  192. return getTask(input, getTempDir());
  193. }
  194. protected AjcTask getTask(String input, File destDir) {
  195. AjcTask task = new AjcTask();
  196. Project p = new Project();
  197. task.setProject(p);
  198. if (null != destDir) {
  199. task.setDestdir(destDir);
  200. }
  201. if (NOFILE.equals(input)) {
  202. // add nothing
  203. } else if (input.endsWith(".lst")) {
  204. if (input.contains(",")) {
  205. throw new IllegalArgumentException(
  206. "lists not supported: " + input);
  207. } else if (null == testdataDir) {
  208. throw new Error("testdata not found - run in ../taskdefs");
  209. } else {
  210. String path = testdataDir + File.separator + input;
  211. task.setArgfiles(new Path(task.getProject(), path));
  212. }
  213. } else if ((input.endsWith(".java") || input.endsWith(".aj"))) {
  214. FilenameSelector fns = new FilenameSelector();
  215. fns.setName(input);
  216. task.addFilename(fns);
  217. } else {
  218. String path = testdataDir + File.separator + input;
  219. task.setSourceRoots(new Path(task.getProject(), path));
  220. }
  221. task.setClasspath(new Path(p, "../lib/test/aspectjrt.jar"));
  222. return task;
  223. }
  224. /** used in testMessageHolderClassName */
  225. public static class InfoHolder extends MessageHandler {
  226. public InfoHolder() {
  227. }
  228. @Override
  229. public boolean handleMessage(IMessage message) {
  230. if (0 == IMessage.INFO.compareTo(message.getKind())) {
  231. AjcTaskTest.collectMessage(message.getMessage());
  232. }
  233. return true;
  234. }
  235. }
  236. /** used in testMessageHolderClassName */
  237. public static class Holder extends MessageHandler {
  238. public Holder() {
  239. }
  240. @Override
  241. public boolean handleMessage(IMessage message) {
  242. IMessage.Kind kind = message.getKind();
  243. if (IMessage.ERROR.isSameOrLessThan(kind)) {
  244. String m = kind.toString();
  245. AjcTaskTest.collectMessage(m.substring(0, 1));
  246. }
  247. return true;
  248. }
  249. }
  250. // ------------------------------------------------------
  251. // ------------------------------------------------------
  252. // ------------------------------------------------------
  253. // ------------------------------------------------------
  254. // ------------------------------------------------------
  255. // ------------------------------------------------------
  256. // Start of test cases
  257. public void testNullDestDir() {
  258. AjcTask task = getTask(NOFILE, null);
  259. String[] cmd = task.makeCommand();
  260. for (String s : cmd) {
  261. assertTrue(!"-d".equals(s));
  262. }
  263. }
  264. public void testOutputRequirement() {
  265. AjcTask task = getTask("default.lst");
  266. checkRun(task, null);
  267. // copyInJars now just emits warning b/c unused
  268. task = getTask("default.lst", null);
  269. task.setCopyInjars(true);
  270. checkRun(task, null);
  271. // sourceRootCopyFilter requires destDir
  272. task = getTask("default.lst", null);
  273. task.setSourceRootCopyFilter("**/*.java");
  274. checkRun(task, "sourceRoot");
  275. }
  276. public void testSourceRootCopyFilter() {
  277. // sourceRootCopyFilter works..
  278. File destDir = getTempDir();
  279. assertTrue(
  280. "unable to create " + destDir,
  281. destDir.canRead() || destDir.mkdirs());
  282. AjcTask task = getTask("sourceroot", destDir);
  283. task.setSourceRootCopyFilter("doNotCopy,**/*.txt");
  284. File file = new File(destDir, "Default.java").getAbsoluteFile();
  285. assertTrue(file + ".canRead() prematurely", !file.canRead());
  286. checkRun(task, null);
  287. // got expected resources
  288. assertTrue(file + ".canRead() failed", file.canRead());
  289. File pack = new File(destDir, "pack");
  290. file = new File(pack, "Pack.java").getAbsoluteFile();
  291. assertTrue(file + ".canRead() failed", file.canRead());
  292. file = new File(pack, "includeme").getAbsoluteFile();
  293. assertTrue(file + ".canRead() failed", file.canRead());
  294. // didn't get unexpected resources
  295. file = new File(pack, "something.txt");
  296. assertTrue(file + ".canRead() passed", !file.canRead());
  297. file = new File(destDir, "doNotCopy");
  298. assertTrue(file + ".canRead() passed", !file.canRead());
  299. file = new File(destDir, "skipTxtFiles.txt");
  300. assertTrue(file + ".canRead() passed", !file.canRead());
  301. }
  302. public void testInpathDirCopyFilter() {
  303. // inpathDirCopyFilter works with output directory
  304. File destDir = getTempDir();
  305. assertTrue(
  306. "unable to create " + destDir,
  307. destDir.canRead() || destDir.mkdirs());
  308. AjcTask task = getTask(NOFILE, destDir);
  309. Project p = task.getProject();
  310. Path indirs = new Path(p);
  311. File dir = new File(testdataDir, "inpathDirs").getAbsoluteFile();
  312. indirs.addExisting(new Path(p, new File(dir, "inpathDirOne").getAbsolutePath()));
  313. indirs.addExisting(new Path(p, new File(dir, "inpathDirTwo").getAbsolutePath()));
  314. task.setInpath(indirs);
  315. task.setInpathDirCopyFilter("doNotCopy,**/*.txt");
  316. File file = new File(destDir, "Default.java").getAbsoluteFile();
  317. assertTrue(file + ".canRead() prematurely", !file.canRead());
  318. checkRun(task, null);
  319. // got expected resources
  320. File pack = new File(destDir, "pack");
  321. file = new File(pack, "includeme").getAbsoluteFile();
  322. assertTrue(file + ".canRead() failed", file.canRead());
  323. file = new File(pack, "Pack.class").getAbsoluteFile();
  324. assertTrue(file + ".canRead() failed", file.canRead());
  325. file = new File(destDir, "copyMe.htm").getAbsoluteFile();
  326. assertTrue(file + ".canRead() failed", file.canRead());
  327. file = new File(destDir, "Default.class").getAbsoluteFile();
  328. assertTrue(file + ".canRead() failed", file.canRead());
  329. // didn't get unexpected resources
  330. file = new File(pack, "something.txt");
  331. assertTrue(file + ".canRead() passed", !file.canRead());
  332. file = new File(destDir, "doNotCopy");
  333. assertTrue(file + ".canRead() passed", !file.canRead());
  334. file = new File(destDir, "skipTxtFiles.txt");
  335. assertTrue(file + ".canRead() passed", !file.canRead());
  336. }
  337. public void testInpathDirCopyFilterWithJar() throws IOException {
  338. checkInpathCopy("testInpathDirCopyFilterWithJar-out.jar");
  339. }
  340. // test resource copying for oddball jar files that don't end in .jar
  341. public void testInpathDirCopyFilterWithOddjar() throws IOException {
  342. checkInpathCopy("testInpathDirCopyFilterWithJar-outJarFile");
  343. }
  344. private void checkInpathCopy(String outjarFileStr) throws IOException {
  345. // inpathDirCopyFilter works with output jar
  346. File destDir = getTempDir();
  347. assertTrue(
  348. "unable to create " + destDir,
  349. destDir.canRead() || destDir.mkdirs());
  350. AjcTask task = getTask(NOFILE, null);
  351. File destJar = new File(destDir, outjarFileStr);
  352. task.setOutjar(destJar);
  353. Project p = task.getProject();
  354. Path indirs = new Path(p);
  355. File dir = new File(testdataDir, "inpathDirs").getAbsoluteFile();
  356. indirs.addExisting(new Path(p, new File(dir, "inpathDirOne").getAbsolutePath()));
  357. indirs.addExisting(new Path(p, new File(dir, "inpathDirTwo").getAbsolutePath()));
  358. task.setInpath(indirs);
  359. task.setInpathDirCopyFilter("doNotCopy,**/*.txt,**/*.class");
  360. checkRun(task, null);
  361. try (JarFile jarFile = new JarFile(destJar)) {
  362. String[] expected = { "copyMe.htm", "pack/includeme",
  363. "pack/Pack.class", "Default.class" };
  364. String[] unexpected = { "doNotCopy", "skipTxtFiles.txt", "pack/something.txt" };
  365. for (String value : expected) {
  366. JarEntry entry = jarFile.getJarEntry(value);
  367. assertTrue(value + " not found", null != entry);
  368. }
  369. for (String s : unexpected) {
  370. JarEntry entry = jarFile.getJarEntry(s);
  371. assertTrue(s + " found", null == entry);
  372. }
  373. }
  374. }
  375. public void testInpathDirCopyFilterError() {
  376. // inpathDirCopyFilter fails with no output directory or jar iff specified
  377. AjcTask task = getTask(NOFILE, null);
  378. Project p = task.getProject();
  379. Path indirs = new Path(p);
  380. File dir = new File(testdataDir, "inpathDirs").getAbsoluteFile();
  381. indirs.addExisting(new Path(p, new File(dir, "inpathDirOne").getAbsolutePath()));
  382. indirs.addExisting(new Path(p, new File(dir, "inpathDirTwo").getAbsolutePath()));
  383. task.setInpath(indirs);
  384. task.setInpathDirCopyFilter("doNotCopy,**/*.txt,**/*.class");
  385. // expecting error
  386. checkRun(task, "inpathDirCopyFilter");
  387. }
  388. // this test method submitted by patch from Andrew Huff (IBM)
  389. // verifies that the log attribute of AjcTask writes output to the given log file
  390. public void testLoggingMode() {
  391. AjcTask task = getTask("default.lst");
  392. task.setFailonerror(false);
  393. File logFile = new File("testLogFile1.txt");
  394. String s = logFile.getAbsolutePath();
  395. logFile.delete();
  396. long initialLength = logFile.length();
  397. task.setLog(logFile);
  398. runTest(task,null,MessageHolderChecker.INFOS);
  399. long newLength = logFile.length();
  400. assertTrue(newLength > initialLength);
  401. logFile.delete();
  402. }
  403. public void testCommandEditor() {
  404. String className = VerboseCommandEditor.class.getName();
  405. System.setProperty(AjcTask.COMMAND_EDITOR_NAME, className);
  406. assertEquals(
  407. className,
  408. System.getProperty(AjcTask.COMMAND_EDITOR_NAME));
  409. AjcTask task = getTask(NOFILE);
  410. task.setCommandEditor(new VerboseCommandEditor());
  411. String[] cmd = task.makeCommand();
  412. assertEquals(VerboseCommandEditor.VERBOSE, cmd[0]);
  413. task = getTask(NOFILE);
  414. task.setCommandEditorClass(VerboseCommandEditor.class.getName());
  415. cmd = task.makeCommand();
  416. assertEquals(VerboseCommandEditor.VERBOSE, cmd[0]);
  417. }
  418. // public void testStaticCommandEditor() {
  419. // // XXX need to test COMMAND_EDITOR, but can't require property when run
  420. // }
  421. public void testLimitTo() {
  422. int numArgs = 100;
  423. String arg = "123456789";
  424. String[] args = new String[numArgs];
  425. for (int i = 0; i < args.length; i++) {
  426. args[i] = arg;
  427. }
  428. // no limit
  429. int max = numArgs * (arg.length() + 1);
  430. Location location = new Location("AjcTaskTest.java");
  431. String[] newArgs = AjcTask.GuardedCommand.limitTo(args, max, location);
  432. assertTrue("same", args == newArgs);
  433. // limited - read file and verify arguments
  434. max--;
  435. newArgs = AjcTask.GuardedCommand.limitTo(args, max, location);
  436. assertTrue("not same", args != newArgs);
  437. assertTrue("not null", null != newArgs);
  438. String label = "newArgs " + Arrays.asList(newArgs);
  439. assertTrue("size 2" + label, 2 == newArgs.length);
  440. assertEquals("-argfile", newArgs[0]);
  441. File file = new File(newArgs[1]);
  442. assertTrue("readable newArgs[1]" + label, file.canRead());
  443. FileReader fin = null;
  444. try {
  445. fin = new FileReader(file);
  446. BufferedReader reader = new BufferedReader(fin);
  447. String line;
  448. int i = 0;
  449. while (null != (line = reader.readLine())) {
  450. assertEquals(i + ": ", args[i++], line);
  451. }
  452. assertEquals("num entries", i, args.length);
  453. } catch (IOException e) {
  454. assertTrue("IOException " + e.getMessage(), false);
  455. } finally {
  456. if (null != fin) {
  457. try {
  458. fin.close();
  459. } catch (IOException e) {
  460. // ignore
  461. }
  462. }
  463. file.delete();
  464. }
  465. }
  466. public void testFindAspectjtoolsJar() {
  467. File toolsJar = AjcTask.findAspectjtoolsJar();
  468. if (null != toolsJar) {
  469. assertNull("tools jar found?: " + toolsJar, toolsJar);
  470. }
  471. // not found when unit testing b/c not on system classpath
  472. // so just checking for exceptions.
  473. // XXX need aspect to stub out System.getProperty(..)
  474. }
  475. public void testMessageHolderClassName() {
  476. AjcTask task = getTask("compileError.lst");
  477. task.setFailonerror(false);
  478. MESSAGES.setLength(0);
  479. runTest(
  480. task,
  481. null,
  482. MessageHolderChecker.ONE_ERROR,
  483. Holder.class.getName());
  484. String result = MESSAGES.toString();
  485. MESSAGES.setLength(0);
  486. // The test program produces three errors with the current 1.8 compiler, this may change by 1.8 release and so
  487. // this will need reverting back to "e"
  488. assertEquals("messages", "eee", result);
  489. }
  490. // TODO skipped test - works locally but not on build machine?
  491. public void skip_testMessageHolderClassWithDoneSignal() {
  492. AjcTask task = getTask("default.lst");
  493. task.setFailonerror(false);
  494. String DONE = "This is a unique message, not confused with others.";
  495. task.setXDoneSignal(DONE);
  496. MESSAGES.setLength(0);
  497. runTest(
  498. task,
  499. null,
  500. MessageHolderChecker.INFOS,
  501. InfoHolder.class.getName());
  502. final String result = MESSAGES.toString();
  503. String temp = new String(result);
  504. MESSAGES.setLength(0);
  505. if (!temp.endsWith(DONE)) {
  506. if (temp.length() > 20) {
  507. temp = "..." + temp.substring(temp.length()-20, temp.length());
  508. }
  509. assertTrue(DONE + " is not suffix of \"" + temp + "\"", false);
  510. }
  511. // exactly one such message
  512. temp = new String(result);
  513. temp = temp.substring(0, temp.length()-DONE.length());
  514. if (temp.endsWith(DONE)) {
  515. temp = new String(result);
  516. if (temp.length() > 20) {
  517. temp = "..." + temp.substring(temp.length()-20, temp.length());
  518. }
  519. assertTrue(DONE + " signalled twice: \"" + temp + "\"", false);
  520. }
  521. }
  522. public void testDefaultListForkedNoTools() {
  523. AjcTask task = getTask("default.lst");
  524. task.setFork(true);
  525. boolean passed = false;
  526. try {
  527. runTest(task, BuildException.class, MessageHolderChecker.NONE);
  528. passed = true;
  529. } finally {
  530. if (!passed) {
  531. String m =
  532. "AjcTaskTest.testDefaultListForkedNoTools()"
  533. + " fails if aspectjtools.jar is on the classpath";
  534. System.err.println(m);
  535. }
  536. }
  537. }
  538. public void testDefaultListForkedIncremental() {
  539. AjcTask task = getTask("default.lst");
  540. task.setFork(true);
  541. task.setIncremental(true);
  542. runTest(task, BuildException.class, MessageHolderChecker.NONE);
  543. }
  544. /** failonerror should default to true, unlike other booleans */
  545. public void testCompileErrorFailOnErrorDefault() {
  546. AjcTask task = getTask("compileError.lst");
  547. final PrintStream serr = System.err;
  548. try {
  549. System.setErr(new PrintStream(new java.io.ByteArrayOutputStream()));
  550. // Current 1.8 compiler produces 3 errors for this test program, may need reverting to ONE_ERROR by release
  551. runTest(task, BuildException.class, MessageHolderChecker.THREE_ERRORS);
  552. } finally {
  553. System.setErr(serr);
  554. }
  555. }
  556. public void testCompileErrorListDefaultHolder() {
  557. AjcTask task = getTask("compileError.lst");
  558. final PrintStream serr = System.err;
  559. try {
  560. System.setErr(new PrintStream(new java.io.ByteArrayOutputStream()));
  561. task.execute();
  562. fail("expected BuildException from failed compile by default");
  563. } catch (BuildException t) {
  564. // ok
  565. } finally {
  566. System.setErr(serr);
  567. deleteTempDir();
  568. }
  569. }
  570. public void testDefaultList() {
  571. AjcTask task = getTask("default.lst");
  572. runTest(task, NO_EXCEPTION, MessageHolderChecker.INFOS);
  573. }
  574. public void testCompileErrorList() {
  575. AjcTask task = getTask("compileError.lst");
  576. task.setFailonerror(false);
  577. // Prior to the 1.8 compiler there is one error here, 'syntax error on here'
  578. // With 1.8 there are 3 errors about completing the method header, ending the class body, ending the method - this may
  579. // change by 1.8 final... this might need reverting back to ONE_ERROR
  580. runTest(task, NO_EXCEPTION, MessageHolderChecker.THREE_ERRORS);
  581. }
  582. public void testShowWeaveInfo() {
  583. AjcTask task = getTask("showweaveinfo.lst");
  584. task.setShowWeaveInfo(true);
  585. MessageHandler mh = new MessageHandler(false);
  586. mh.dontIgnore(IMessage.WEAVEINFO);
  587. MessageHolderChecker mhc = new MessageHolderChecker(0,0,0,0,MessageHolderChecker.IGNORE);
  588. mhc.weaveinfos = 2; // Expect 2 weaving messages
  589. runTest(task,NO_EXCEPTION,mhc);
  590. mhc.weaveinfos = MessageHolderChecker.IGNORE;
  591. }
  592. public void testCompileWarningList() {
  593. AjcTask task = getTask("compileWarning.lst");
  594. runTest(task, NO_EXCEPTION, MessageHolderChecker.ONE_WARNING);
  595. }
  596. public void testNoSuchFileList() {
  597. AjcTask task = getTask("NoSuchFile.lst");
  598. task.setFailonerror(false);
  599. runTest(task, NO_EXCEPTION, MessageHolderChecker.ONE_ERROR);
  600. }
  601. public void testVersions() {
  602. String[] inputs = AjcTask.TARGET_INPUTS;
  603. for (String value : inputs) {
  604. AjcTask task = getTask(NOFILE);
  605. task.setTarget(value);
  606. String[] cmd = task.makeCommand();
  607. checkContains(cmd, "-target", true);
  608. checkContains(cmd, value, true);
  609. }
  610. inputs = AjcTask.SOURCE_INPUTS;
  611. for (String s : inputs) {
  612. AjcTask task = getTask(NOFILE);
  613. task.setSource(s);
  614. String[] cmd = task.makeCommand();
  615. checkContains(cmd, "-source", true);
  616. checkContains(cmd, s, true);
  617. }
  618. inputs = AjcTask.COMPLIANCE_INPUTS;
  619. for (String input : inputs) {
  620. AjcTask task = getTask(NOFILE);
  621. task.setCompliance(input);
  622. String[] cmd = task.makeCommand();
  623. checkContains(cmd, input, true);
  624. }
  625. }
  626. public void testClasspath() {
  627. AjcTask task = getTask(NOFILE);
  628. String[] cmd = task.makeCommand();
  629. checkContains(cmd, "-bootclasspath", false);
  630. String classpath = null;
  631. for (int i = 0; i < cmd.length; i++) {
  632. if ("-classpath".equals(cmd[i])) {
  633. classpath = cmd[i + 1];
  634. break;
  635. }
  636. }
  637. assertTrue(
  638. "expecting aspectj in classpath",
  639. (classpath.contains("aspectjrt.jar")));
  640. }
  641. CompilerArg createCompilerArg(String value) {
  642. CompilerArg c = new CompilerArg();
  643. c.setValue(value);
  644. return c;
  645. }
  646. public void testAddModulesJ9() {
  647. AjcTask task = getTask(NOFILE);
  648. task.createCompilerarg().setValue("--add-modules");
  649. task.createCompilerarg().setValue("java.xml.bind,java.io");
  650. String[] cmd = task.makeCommand();
  651. System.out.println(Arrays.toString(cmd));
  652. int addModulesPos = findOptionPosition(cmd,"--add-modules");
  653. assertNotSame(-1, addModulesPos);
  654. assertEquals("java.xml.bind,java.io",cmd[addModulesPos+1]);
  655. }
  656. private int findOptionPosition(String[] cmd, String optionString) {
  657. for (int i=0;i<cmd.length;i++) {
  658. if (cmd[i].equals(optionString)) {
  659. return i;
  660. }
  661. }
  662. return -1;
  663. }
  664. // ---------------------------------------- sourcefile
  665. // XXX need to figure out how to specify files directly programmatically
  666. // public void testDefaultFile() {
  667. // AjcTask task = getTask("testdata/Default.java");
  668. // runTest(task, NO_EXCEPTION, MessageHolderChecker.INFOS);
  669. // }
  670. public void testNoFile() {
  671. AjcTask task = getTask(NOFILE);
  672. task.setFailonerror(false);
  673. runTest(task, NO_EXCEPTION, MessageHolderChecker.ONE_ERROR);
  674. }
  675. public void testCompileErrorFile() {
  676. AjcTask task = getTask("compileError.lst");
  677. task.setFailonerror(false);
  678. // 1.8 compiler currently produces 3 errors for the test program, may need to revert to ONE_ERROR by 1.8 release
  679. runTest(task, NO_EXCEPTION, MessageHolderChecker.THREE_ERRORS);
  680. }
  681. public void testCompileWarningFile() {
  682. AjcTask task = getTask("compileWarning.lst");
  683. task.setFailonerror(false);
  684. runTest(task, NO_EXCEPTION, MessageHolderChecker.ONE_WARNING);
  685. }
  686. public void testNoSuchFile() {
  687. AjcTask task = getTask("NoSuchFile.lst");
  688. task.setFailonerror(false);
  689. runTest(task, NO_EXCEPTION, MessageHolderChecker.ONE_ERROR);
  690. }
  691. public void testDefaultFileComplete() {
  692. AjcTask task = getTask("default.lst");
  693. defaultSettings(task);
  694. runTest(task, NO_EXCEPTION, MessageHolderChecker.INFOS);
  695. }
  696. private void defaultSettings(AjcTask task) {
  697. task.setDebugLevel("none");
  698. task.setDeprecation(true);
  699. task.setFailonerror(false);
  700. task.setNoExit(true); // ok to override Ant?
  701. task.setNoImportError(true);
  702. task.setNowarn(true);
  703. task.setXTerminateAfterCompilation(true);
  704. task.setPreserveAllLocals(true);
  705. task.setProceedOnError(true);
  706. task.setReferenceInfo(true);
  707. task.setSource("1.3");
  708. task.setTarget("1.1");
  709. task.setTime(true);
  710. task.setVerbose(true);
  711. task.setXlint("info");
  712. }
  713. public void testLogCommand() {
  714. final String DEFAULT = "default.lst";
  715. AjcTask task = getTask(DEFAULT);
  716. defaultSettings(task);
  717. task.setVerbose(false);
  718. task.setLogCommand(true);
  719. LogListener listener = new LogListener(Project.MSG_INFO);
  720. task.getProject().addBuildListener(listener);
  721. runTest(task, NO_EXCEPTION, MessageHolderChecker.INFOS);
  722. String[] results = listener.getResults();
  723. boolean matched = false;
  724. for (int i = 0; !matched && (i < results.length); i++) {
  725. String s = results[i];
  726. matched = (null != s) && (s.contains(DEFAULT));
  727. }
  728. if (!matched) {
  729. fail(DEFAULT + " not found in " + Arrays.asList(results));
  730. }
  731. }
  732. public void testXOptions() {
  733. String[] xopts = new String[] {
  734. "serializableAspects",
  735. "lazyTjp",
  736. "reweavable",
  737. "reweavable:compress",
  738. "noInline"
  739. };
  740. for (String xopt : xopts) {
  741. AjcTask task = getTask(NOFILE);
  742. task.setX(xopt);
  743. String[] cmd = task.makeCommand();
  744. checkContains(cmd, "-X" + xopt, true);
  745. }
  746. }
  747. public void testAptProc() {
  748. AjcTask task = getTask(NOFILE);
  749. task.setProc("none");
  750. checkContains(task.makeCommand(), "-proc:none", true);
  751. task.setProc("only");
  752. checkContains(task.makeCommand(), "-proc:only", true);
  753. }
  754. public void testAptProcessor() {
  755. AjcTask task = getTask(NOFILE);
  756. task.setProcessor("some.SomeClass");
  757. checkContains(task.makeCommand(), "-processor", true);
  758. checkContains(task.makeCommand(), "some.SomeClass", true);
  759. }
  760. public void testAptProcessorpath() {
  761. AjcTask task = getTask(NOFILE);
  762. task.setProcessorpath("some/path");
  763. checkContains(task.makeCommand(), "-processorpath", true);
  764. checkContains(task.makeCommand(), "some/path", true);
  765. }
  766. public void testAptGeneratedDirectory() {
  767. AjcTask task = getTask(NOFILE);
  768. task.setS("some/path");
  769. checkContains(task.makeCommand(), "-s", true);
  770. checkContains(task.makeCommand(), "some/path", true);
  771. }
  772. public void testOutxml () {
  773. File destDir = getTempDir();
  774. assertTrue(
  775. "unable to create " + destDir,
  776. destDir.canRead() || destDir.mkdirs());
  777. AjcTask task = getTask("showweaveinfo.lst",destDir);
  778. task.setOutxml(true);
  779. checkRun(task,null);
  780. File outxmlFile = new File(destDir,"META-INF/aop-ajc.xml");
  781. assertTrue("META-INF/aop-ajc.xml missing",outxmlFile.exists());
  782. }
  783. public void testOutxmlFile () {
  784. String customName = "custom/aop.xml";
  785. File destDir = getTempDir();
  786. assertTrue(
  787. "unable to create " + destDir,
  788. destDir.canRead() || destDir.mkdirs());
  789. AjcTask task = getTask("showweaveinfo.lst",destDir);
  790. task.setOutxmlfile(customName);
  791. checkRun(task,null);
  792. File outxmlFile = new File(destDir,customName);
  793. assertTrue(customName + " missing",outxmlFile.exists());
  794. }
  795. // End of test cases
  796. // ------------------------------------------------------
  797. // ------------------------------------------------------
  798. // ------------------------------------------------------
  799. // ------------------------------------------------------
  800. // ------------------------------------------------------
  801. // ------------------------------------------------------
  802. protected void runTest(
  803. AjcTask task,
  804. Class exceptionType,
  805. MessageHolderChecker checker,
  806. String messageHolderClass) {
  807. task.setMessageHolderClass(messageHolderClass);
  808. runTest(task, exceptionType, checker, (MessageHandler) null);
  809. }
  810. protected void runTest(
  811. AjcTask task,
  812. Class exceptionType,
  813. MessageHolderChecker checker) {
  814. MessageHandler holder = new MessageHandler();
  815. task.setMessageHolder(holder);
  816. runTest(task, exceptionType, checker, holder);
  817. }
  818. protected void runTest(
  819. AjcTask task,
  820. Class exceptionType,
  821. MessageHolderChecker checker,
  822. MessageHandler holder) {
  823. Throwable thrown = null;
  824. // re-run forked iff tools.jar and expect to pass
  825. boolean rerunForked =
  826. ((null != aspectjtoolsJar)
  827. && (null == exceptionType)
  828. && ((null == checker) || !checker.expectFail()));
  829. String label = "same-vm ";
  830. while (true) { // same vm, then perhaps forked
  831. try {
  832. task.execute();
  833. } catch (Throwable t) {
  834. thrown = t;
  835. } finally {
  836. deleteTempDir();
  837. }
  838. if (null == exceptionType) {
  839. if (null != thrown) {
  840. assertTrue(label + "thrown: " + render(thrown), false);
  841. }
  842. } else if (null == thrown) {
  843. assertTrue(
  844. label + "expected " + exceptionType.getName(),
  845. false);
  846. } else if (!(exceptionType.isAssignableFrom(thrown.getClass()))) {
  847. assertTrue(
  848. label
  849. + "expected "
  850. + exceptionType.getName()
  851. + " got "
  852. + render(thrown),
  853. false);
  854. }
  855. if (null != holder) {
  856. if (null == checker) {
  857. checker = MessageHolderChecker.NONE;
  858. }
  859. checker.check(holder, label);
  860. }
  861. if (!rerunForked) {
  862. break;
  863. } else {
  864. label = "other-vm ";
  865. rerunForked = false;
  866. // can't reset without losing values...
  867. task.setFork(true);
  868. task.setFailonerror(true);
  869. task.setForkclasspath(
  870. new Path(task.getProject(), aspectjtoolsJar));
  871. }
  872. }
  873. }
  874. protected String render(Throwable thrown) {
  875. return LangUtil.renderException(thrown);
  876. }
  877. static class MessageHolderChecker { // XXX export to testing-utils
  878. /** use as value to ignore results */
  879. static int IGNORE = Integer.MIN_VALUE;
  880. static MessageHolderChecker NONE =
  881. new MessageHolderChecker(0, 0, 0, 0, 0);
  882. /** any number (0+) of info messages */
  883. static MessageHolderChecker INFOS =
  884. new MessageHolderChecker(0, 0, 0, 0, IGNORE);
  885. /** one error, any number of info messages */
  886. static MessageHolderChecker ONE_ERROR =
  887. new MessageHolderChecker(0, 0, 1, 0, IGNORE);
  888. static MessageHolderChecker ONE_ERROR_ONE_ABORT =
  889. new MessageHolderChecker(1, 0, 1, 0, IGNORE);
  890. /** one warning, any number of info messages */
  891. static MessageHolderChecker ONE_WARNING =
  892. new MessageHolderChecker(0, 0, 0, 1, IGNORE);
  893. static MessageHolderChecker THREE_ERRORS =
  894. new MessageHolderChecker(0, 0, 3, 0, IGNORE);
  895. int aborts, fails, errors, warnings, infos;
  896. int weaveinfos;
  897. public MessageHolderChecker(
  898. int aborts,
  899. int fails,
  900. int errors,
  901. int warnings,
  902. int infos) {
  903. this.aborts = aborts;
  904. this.fails = fails;
  905. this.errors = errors;
  906. this.warnings = warnings;
  907. this.infos = infos;
  908. this.weaveinfos = IGNORE;
  909. }
  910. public boolean expectFail() {
  911. return (0 < (aborts + fails + errors));
  912. }
  913. public void check(IMessageHolder holder, String label) {
  914. boolean failed = true;
  915. try {
  916. check(holder, aborts, IMessage.ABORT);
  917. check(holder, fails, IMessage.FAIL);
  918. check(holder, errors, IMessage.ERROR);
  919. check(holder, warnings, IMessage.WARNING);
  920. check(holder, infos, IMessage.INFO);
  921. check(holder, weaveinfos, IMessage.WEAVEINFO);
  922. failed = false;
  923. } finally {
  924. if (failed) {
  925. MessageUtil.print(System.err, holder, label + "failed?");
  926. }
  927. }
  928. }
  929. private void check(
  930. IMessageHolder holder,
  931. int num,
  932. IMessage.Kind kind) {
  933. if (num != IGNORE) {
  934. int actual = holder.numMessages(kind, false);
  935. // Filter out a warning which occurs, if the current release does not match the stored binary in lib/test.
  936. // If e.g. we run tests for a milestone release a.b.5.M1 and afterwards switch back to a.b.5-SNAPSHOT, we do not
  937. // want to update lib/test for a single commit, just to make this test pass. Hence, we ignore this warning here.
  938. if (kind.equals(IMessage.WARNING)) {
  939. for (IMessage message : holder.getMessages(kind, false)) {
  940. String warningMessage = message.getMessage();
  941. if (warningMessage.matches("bad version number found in .*aspectjrt.jar expected .* found .*"))
  942. actual--;
  943. }
  944. }
  945. if (num != actual) {
  946. if (actual > 0) {
  947. MessageUtil.print(
  948. System.err,
  949. holder,
  950. kind + " expected " + num + " got " + actual);
  951. }
  952. System.out.println("===\n" + Arrays.toString(holder.getMessages(kind, false)) + "\n===\n");
  953. assertEquals(kind.toString(), num, actual);
  954. }
  955. }
  956. }
  957. }
  958. private static class LogListener implements BuildListener {
  959. private final ArrayList results = new ArrayList();
  960. private final int priority;
  961. private LogListener(int priority) {
  962. this.priority = priority;
  963. }
  964. @Override
  965. public void buildFinished(BuildEvent event) {}
  966. @Override
  967. public void buildStarted(BuildEvent event) {}
  968. @Override
  969. public void messageLogged(BuildEvent event) {
  970. if (priority == event.getPriority()) {
  971. results.add(event.getMessage());
  972. }
  973. }
  974. @Override
  975. public void targetFinished(BuildEvent event) {}
  976. @Override
  977. public void targetStarted(BuildEvent event) {}
  978. @Override
  979. public void taskFinished(BuildEvent event) {}
  980. @Override
  981. public void taskStarted(BuildEvent event) {}
  982. String[] getResults() {
  983. return (String[]) results.toArray(new String[0]);
  984. }
  985. }
  986. }
  987. class SnoopingCommandEditor implements ICommandEditor {
  988. private static final String[] NONE = new String[0];
  989. String[] lastCommand;
  990. @Override
  991. public String[] editCommand(String[] command) {
  992. lastCommand = (String[]) LangUtil.safeCopy(command, NONE);
  993. return command;
  994. }
  995. public String[] lastCommand() {
  996. return (String[]) LangUtil.safeCopy(lastCommand, NONE);
  997. }
  998. }
  999. class VerboseCommandEditor implements ICommandEditor {
  1000. public static final String VERBOSE = "-verbose";
  1001. @Override
  1002. public String[] editCommand(String[] command) {
  1003. for (String s : command) {
  1004. if (VERBOSE.equals(s)) {
  1005. return command;
  1006. }
  1007. }
  1008. String[] result = new String[1 + command.length];
  1009. result[0] = VERBOSE;
  1010. System.arraycopy(result, 1, command, 0, command.length);
  1011. return result;
  1012. }
  1013. }
  1014. class AppendingCommandEditor implements ICommandEditor {
  1015. private static String[] NONE = new String[0];
  1016. public static ICommandEditor VERBOSE =
  1017. new AppendingCommandEditor(new String[] { "-verbose" }, NONE);
  1018. public static ICommandEditor INVALID =
  1019. new AppendingCommandEditor(NONE, new String[] { "-invalidOption" });
  1020. final String[] prefix;
  1021. final String[] suffix;
  1022. public AppendingCommandEditor(String[] prefix, String[] suffix) {
  1023. this.prefix = prefix;
  1024. this.suffix = suffix;
  1025. }
  1026. @Override
  1027. public String[] editCommand(String[] command) {
  1028. int len = command.length + prefix.length + suffix.length;
  1029. String[] result = new String[len];
  1030. System.arraycopy(result, 0, prefix, 0, prefix.length);
  1031. System.arraycopy(result, prefix.length, command, 0, command.length);
  1032. System.arraycopy(
  1033. result,
  1034. prefix.length + command.length,
  1035. suffix,
  1036. 0,
  1037. suffix.length);
  1038. return result;
  1039. }
  1040. }