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.

ShowWeaveMessagesTest.java 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /* *******************************************************************
  2. * Copyright (c) 2004 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Andy Clement Initial version
  11. * Helen Hawkins Converted to new interface (bug 148190)
  12. * ******************************************************************/
  13. package org.aspectj.ajde.core.tests;
  14. import java.io.BufferedReader;
  15. import java.io.File;
  16. import java.io.FileReader;
  17. import java.io.FileWriter;
  18. import java.util.ArrayList;
  19. import java.util.HashSet;
  20. import java.util.Hashtable;
  21. import java.util.Iterator;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.Set;
  25. import org.aspectj.ajde.core.AjdeCoreTestCase;
  26. import org.aspectj.ajde.core.JavaOptions;
  27. import org.aspectj.ajde.core.TestCompilerConfiguration;
  28. import org.aspectj.ajde.core.TestMessageHandler;
  29. import org.aspectj.bridge.IMessage;
  30. import org.aspectj.util.LangUtil;
  31. /**
  32. * Weaving messages are complicated things. There are multiple places where weaving takes place and the places vary depending on
  33. * whether we are doing a binary weave or going from source. All places that output weaving messages are tagged: // TAG:
  34. * WeavingMessage so you can easily find them!
  35. *
  36. * Advice is the simplest to deal with as that is advice weaving is always done in the weaver.
  37. *
  38. * Next is intertype declarations. These are also always done in the weaver but in the case of a binary weave we don't know the
  39. * originating source line for the ITD.
  40. *
  41. * Finally, declares. Declare Parents: extends Can only be done when going from source, if attempted by a binary weave then an error
  42. * message (compiler limitation) is produced. Declare Parents: implements Is (currently!) done at both compile time and weave time.
  43. * If going from source then the message is produced by the code in the compiler. if going from binary then the message is produced
  44. * by the weaver. Declare Soft: Comes out with 'advice' as a special kind of advice: softener advice
  45. *
  46. *
  47. * Q: Where are the messages turned on/off? A: It is a bit messy. See BuildArgParser.genBuildConfig(). Basically that method is the
  48. * first time we parse the option set. Whether weaving messages are on or off is stored in the build config. As soon as we have
  49. * parser the options and determined that weave messages are on, we grab the top level message handler and tell it not to ignore
  50. * WeaveInfo messages.
  51. *
  52. *
  53. * TODO - Other forms of declare? Do they need messages? e.g. declare precedence *
  54. */
  55. public class ShowWeaveMessagesTest extends AjdeCoreTestCase {
  56. private static boolean regenerate;
  57. private static boolean debugTests = false;
  58. static {
  59. // Switch this to true for a single iteration if you want to reconstruct the
  60. // 'expected weaving messages' files.
  61. regenerate = false;
  62. }
  63. public static final String PROJECT_DIR = "WeaveInfoMessagesTest";
  64. public static final String binDir = "bin";
  65. public static final String expectedResultsDir = "expected";
  66. public String[] one = new String[] { "AspectAdvice.aj", "Simple.java" };
  67. public String[] two = new String[] { "AspectITD.aj", "Simple.java" };
  68. public String[] three = new String[] { "AspectDeclare.aj", "Simple.java" };
  69. public String[] four = new String[] { "AspectDeclareExtends.aj", "Simple.java" };
  70. public String[] five = new String[] { "Simple.java", "AspectDeclareSoft.aj" };
  71. public String[] six = new String[] { "AspectDeclareAnnotations.aj" };
  72. public String[] seven = new String[] { "AspectDeclareAnnotations.aj" };
  73. public String[] empty = new String[] {};
  74. private TestMessageHandler handler;
  75. private TestCompilerConfiguration compilerConfig;
  76. @Override
  77. protected void setUp() throws Exception {
  78. super.setUp();
  79. initialiseProject(PROJECT_DIR);
  80. handler = (TestMessageHandler) getCompiler().getMessageHandler();
  81. handler.dontIgnore(IMessage.WEAVEINFO);
  82. compilerConfig = (TestCompilerConfiguration) getCompiler().getCompilerConfiguration();
  83. compilerConfig.setNonStandardOptions("-showWeaveInfo");
  84. }
  85. @Override
  86. protected void tearDown() throws Exception {
  87. super.tearDown();
  88. handler = null;
  89. compilerConfig = null;
  90. }
  91. /**
  92. * Weave all the possible kinds of advice and verify the messages that come out.
  93. */
  94. public void testWeaveMessagesAdvice() {
  95. if (debugTests)
  96. System.out.println("testWeaveMessagesAdvice: Building with One.lst");
  97. compilerConfig.setProjectSourceFiles(getSourceFileList(one));
  98. doBuild();
  99. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  100. verifyWeavingMessages("advice", true);
  101. }
  102. /**
  103. * Weave field and method ITDs and check the weave messages that come out.
  104. */
  105. public void testWeaveMessagesITD() {
  106. if (debugTests)
  107. System.out.println("\ntestWeaveMessagesITD: Building with Two.lst");
  108. compilerConfig.setProjectSourceFiles(getSourceFileList(two));
  109. doBuild();
  110. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  111. verifyWeavingMessages("itd", true);
  112. }
  113. /**
  114. * Weave "declare parents: implements" and check the weave messages that come out.
  115. */
  116. public void testWeaveMessagesDeclare() {
  117. if (debugTests)
  118. System.out.println("\ntestWeaveMessagesDeclare: Building with Three.lst");
  119. compilerConfig.setProjectSourceFiles(getSourceFileList(three));
  120. doBuild();
  121. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  122. verifyWeavingMessages("declare1", true);
  123. }
  124. /**
  125. * Weave "declare parents: extends" and check the weave messages that come out. Can't do equivalent binary test - as can't do
  126. * extends in binary.
  127. */
  128. public void testWeaveMessagesDeclareExtends() {
  129. if (debugTests)
  130. System.out.println("\ntestWeaveMessagesDeclareExtends: Building with Four.lst");
  131. compilerConfig.setProjectSourceFiles(getSourceFileList(four));
  132. doBuild();
  133. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  134. verifyWeavingMessages("declare.extends", true);
  135. }
  136. /**
  137. * Weave "declare soft: type: pointcut" and check the weave messages that come out.
  138. */
  139. public void testWeaveMessagesDeclareSoft() {
  140. if (debugTests)
  141. System.out.println("\ntestWeaveMessagesDeclareSoft: Building with Five.lst");
  142. compilerConfig.setProjectSourceFiles(getSourceFileList(five));
  143. doBuild();
  144. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  145. verifyWeavingMessages("declare.soft", true);
  146. }
  147. /**
  148. * Weave 'declare @type, @constructor, @method and @field' and check the weave messages that come out.
  149. */
  150. public void testWeaveMessagesDeclareAnnotation() {
  151. if (!LangUtil.is15VMOrGreater())
  152. return; // annotation classes won't be about pre 15
  153. if (debugTests)
  154. System.out.println("\ntestWeaveMessagesDeclareAnnotation: Building with Six.lst");
  155. compilerConfig.setProjectSourceFiles(getSourceFileList(six));
  156. setRunIn15Mode();
  157. compilerConfig.setNonStandardOptions("-showWeaveInfo -1.5");
  158. doBuild();
  159. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  160. verifyWeavingMessages("declare.annotation", true);
  161. }
  162. /**
  163. * Weave 'declare @type, @constructor, @method and @field' and check the weave messages don't come out without the
  164. * -showWeaveInfo arg.
  165. */
  166. public void testWeaveMessagesDeclareAnnotationWeaveInfoOff() {
  167. if (debugTests)
  168. System.out.println("\ntestWeaveMessagesDeclareAnnotation: Building with Seven.lst");
  169. compilerConfig.setProjectSourceFiles(getSourceFileList(seven));
  170. compilerConfig.setNonStandardOptions("");
  171. setRunIn15Mode();
  172. doBuild();
  173. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  174. verifyWeavingMessages("declare.annotationNoWeaveInfo", true);
  175. }
  176. // BINARY WEAVING TESTS
  177. /**
  178. * Binary weave variant of the advice weaving test above - to check messages are ok for binary weave. Unlike the source level
  179. * weave, in this test we are using an aspect on the aspectpath - which means it has already had its necessary parts woven - so
  180. * the list of weaving messages we expect is less.
  181. */
  182. public void testWeaveMessagesBinaryAdvice() {
  183. if (debugTests)
  184. System.out.println("\ntestWeaveMessagesBinaryAdvice: Simple.jar + AspectAdvice.jar");
  185. Set<File> inpath = new HashSet<File>();
  186. inpath.add(openFile("Simple.jar"));
  187. compilerConfig.setInpath(inpath);
  188. Set<File> aspectpath = new HashSet<File>();
  189. aspectpath.add(openFile("AspectAdvice.jar"));
  190. compilerConfig.setAspectPath(aspectpath);
  191. doBuild();
  192. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  193. verifyWeavingMessages("advice.binary", true);
  194. }
  195. public void testWeaveMessagesBinaryITD() {
  196. if (debugTests)
  197. System.out.println("\ntestWeaveMessagesBinaryITD: Simple.jar + AspectITD.jar");
  198. Set<File> inpath = new HashSet<File>();
  199. inpath.add(openFile("Simple.jar"));
  200. compilerConfig.setInpath(inpath);
  201. Set<File> aspectpath = new HashSet<File>();
  202. aspectpath.add(openFile("AspectITD.jar"));
  203. compilerConfig.setAspectPath(aspectpath);
  204. doBuild();
  205. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  206. verifyWeavingMessages("itd", false);
  207. }
  208. public void testWeaveMessagesBinaryDeclare() {
  209. if (debugTests)
  210. System.out.println("\ntestWeaveMessagesBinaryDeclare: Simple.jar + AspectDeclare.jar");
  211. Set<File> inpath = new HashSet<File>();
  212. inpath.add(openFile("Simple.jar"));
  213. compilerConfig.setInpath(inpath);
  214. Set<File> aspectpath = new HashSet<File>();
  215. aspectpath.add(openFile("AspectDeclare.jar"));
  216. compilerConfig.setAspectPath(aspectpath);
  217. doBuild();
  218. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  219. verifyWeavingMessages("declare1", false);
  220. }
  221. /**
  222. * Weave "declare soft: type: pointcut" and check the weave messages that come out.
  223. */
  224. public void testWeaveMessagesBinaryDeclareSoft() {
  225. if (debugTests)
  226. System.out.println("\ntestWeaveMessagesBinaryDeclareSoft: Simple.jar + AspectDeclareSoft.jar");
  227. Set<File> inpath = new HashSet<File>();
  228. inpath.add(openFile("Simple.jar"));
  229. compilerConfig.setInpath(inpath);
  230. Set<File> aspectpath = new HashSet<File>();
  231. aspectpath.add(openFile("AspectDeclareSoft.jar"));
  232. compilerConfig.setAspectPath(aspectpath);
  233. doBuild();
  234. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  235. verifyWeavingMessages("declare.soft.binary", true);
  236. }
  237. public void testWeaveMessagesBinaryAdviceInPackageFromJar() {
  238. if (debugTests)
  239. System.out.println("\ntestWeaveMessagesBinaryAdviceInPackageFromJar: Simple.jar + AspectInPackage.jar");
  240. Set<File> inpath = new HashSet<File>();
  241. inpath.add(openFile("Simple.jar"));
  242. compilerConfig.setInpath(inpath);
  243. Set<File> aspectpath = new HashSet<File>();
  244. aspectpath.add(openFile("AspectInPackage.jar"));
  245. compilerConfig.setAspectPath(aspectpath);
  246. doBuild();
  247. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  248. verifyWeavingMessages("advice.binary.package.jar", true);
  249. }
  250. public void testWeaveMessagesBinaryAdviceInPackage() {
  251. if (debugTests)
  252. System.out.println("\ntestWeaveMessagesBinaryAdviceInPackage: Simple.jar + AspectInPackage.jar");
  253. Set<File> inpath = new HashSet<File>();
  254. inpath.add(openFile("Simple.jar"));
  255. compilerConfig.setInpath(inpath);
  256. Set<File> aspectpath = new HashSet<File>();
  257. aspectpath.add(openFile("pkg"));
  258. compilerConfig.setAspectPath(aspectpath);
  259. doBuild();
  260. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  261. verifyWeavingMessages("advice.binary.package", true);
  262. }
  263. // BINARY WEAVING WHEN WE'VE LOST THE SOURCE POINTERS
  264. public void testWeaveMessagesBinaryAdviceNoDebugInfo() {
  265. if (debugTests)
  266. System.out.println("\ntestWeaveMessagesBinaryAdvice: Simple.jar + AspectAdvice.jar");
  267. Set<File> inpath = new HashSet<File>();
  268. inpath.add(openFile("Simple_nodebug.jar"));
  269. compilerConfig.setInpath(inpath);
  270. Set<File> aspectpath = new HashSet<File>();
  271. aspectpath.add(openFile("AspectAdvice_nodebug.jar"));
  272. compilerConfig.setAspectPath(aspectpath);
  273. doBuild();
  274. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  275. verifyWeavingMessages("advice.binary.nodebug", true);
  276. }
  277. public void testWeaveMessagesBinaryITDNoDebugInfo() {
  278. if (debugTests)
  279. System.out.println("\ntestWeaveMessagesBinaryITD: Simple.jar + AspectITD.jar");
  280. Set<File> inpath = new HashSet<>();
  281. inpath.add(openFile("Simple_nodebug.jar"));
  282. compilerConfig.setInpath(inpath);
  283. Set<File> aspectpath = new HashSet<>();
  284. aspectpath.add(openFile("AspectITD_nodebug.jar"));
  285. compilerConfig.setAspectPath(aspectpath);
  286. doBuild();
  287. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  288. verifyWeavingMessages("itd.nodebug", true);
  289. }
  290. public void testWeaveMessagesBinaryDeclareNoDebugInfo() {
  291. if (debugTests)
  292. System.out.println("\ntestWeaveMessagesBinaryDeclareNoDebugInfo: Simple.jar + AspectDeclare.jar");
  293. Set<File> inpath = new HashSet<File>();
  294. inpath.add(openFile("Simple_nodebug.jar"));
  295. compilerConfig.setInpath(inpath);
  296. Set<File> aspectpath = new HashSet<File>();
  297. aspectpath.add(openFile("AspectDeclare_nodebug.jar"));
  298. compilerConfig.setAspectPath(aspectpath);
  299. doBuild();
  300. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  301. verifyWeavingMessages("declare1.nodebug", true);
  302. }
  303. /**
  304. * Weave "declare soft: type: pointcut" and check the weave messages that come out.
  305. */
  306. public void testWeaveMessagesBinaryDeclareSoftNoDebugInfo() {
  307. if (debugTests)
  308. System.out.println("\ntestWeaveMessagesBinaryDeclareSoftNoDebugInfo: Simple.jar + AspectDeclareSoft.jar");
  309. Set<File> inpath = new HashSet<File>();
  310. inpath.add(openFile("Simple_nodebug.jar"));
  311. compilerConfig.setInpath(inpath);
  312. Set<File> aspectpath = new HashSet<File>();
  313. aspectpath.add(openFile("AspectDeclareSoft_nodebug.jar"));
  314. compilerConfig.setAspectPath(aspectpath);
  315. doBuild();
  316. assertTrue("Expected no compiler errors but found " + handler.getErrors(), handler.getErrors().isEmpty());
  317. verifyWeavingMessages("declare.soft.binary.nodebug", true);
  318. }
  319. public void verifyWeavingMessages(String testid, boolean source) {
  320. File expectedF = openFile(expectedResultsDir + File.separator + testid + ".txt");
  321. if (regenerate && source) {
  322. // Create the file
  323. saveWeaveMessages(expectedF);
  324. } else {
  325. // Verify the file matches what we have
  326. compareWeaveMessages(expectedF);
  327. }
  328. }
  329. /**
  330. * Compare weaving messages with what is in the file
  331. */
  332. private void compareWeaveMessages(File f) {
  333. List<String> fileContents = new ArrayList<>();
  334. BufferedReader fr;
  335. try {
  336. // Load the file in
  337. fr = new BufferedReader(new FileReader(f));
  338. String line = null;
  339. while ((line = fr.readLine()) != null)
  340. fileContents.add(line);
  341. List<String> originalFileContents = new ArrayList<>();
  342. originalFileContents.addAll(fileContents);
  343. // See if the messages match
  344. int msgCount = 0;
  345. List<TestMessageHandler.TestMessage> l = handler.getMessages();
  346. for (TestMessageHandler.TestMessage testMessage : l) {
  347. IMessage msg = testMessage.getContainedMessage();
  348. if (debugTests)
  349. System.out.println("Looking at [" + msg + "]");
  350. if (msg.getKind().equals(IMessage.WEAVEINFO)) {
  351. if (!fileContents.contains(msg.getMessage())) {
  352. fail("Could not find message '" + msg.getMessage() + "' in the expected results. Expected results are:\n"
  353. + stringify(originalFileContents));
  354. } else {
  355. fileContents.remove(msg.getMessage());
  356. }
  357. msgCount++;
  358. }
  359. }
  360. assertTrue("Didn't get these expected messages: " + fileContents, fileContents.size() == 0);
  361. if (debugTests)
  362. System.out.println("Successfully verified " + msgCount + " weaving messages");
  363. } catch (Exception e) {
  364. fail("Unexpected exception saving weaving messages:" + e);
  365. }
  366. }
  367. private String stringify(List<String> l) {
  368. StringBuffer result = new StringBuffer();
  369. for (String str: l) {
  370. result.append(str);
  371. result.append("\n");
  372. }
  373. return result.toString();
  374. }
  375. /**
  376. * Store the weaving messages in the specified file.
  377. */
  378. private void saveWeaveMessages(File f) {
  379. System.out.println("Saving weave messages into " + f.getName());
  380. FileWriter fw;
  381. try {
  382. fw = new FileWriter(f);
  383. List<TestMessageHandler.TestMessage> l = handler.getMessages();
  384. for (TestMessageHandler.TestMessage testMessage : l) {
  385. IMessage msg = testMessage.getContainedMessage();
  386. if (msg.getKind().equals(IMessage.WEAVEINFO)) {
  387. fw.write(msg.getMessage() + "\n");
  388. }
  389. }
  390. fw.close();
  391. } catch (Exception e) {
  392. fail("Unexpected exception saving weaving messages:" + e);
  393. }
  394. }
  395. private void setRunIn15Mode() {
  396. Map<String, String> m = new Hashtable<>();
  397. m.put(JavaOptions.COMPLIANCE_LEVEL, JavaOptions.VERSION_15);
  398. m.put(JavaOptions.SOURCE_COMPATIBILITY_LEVEL, JavaOptions.VERSION_15);
  399. m.put(JavaOptions.TARGET_COMPATIBILITY_LEVEL, JavaOptions.VERSION_15);
  400. compilerConfig.setJavaOptions(m);
  401. }
  402. }