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 35KB

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