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

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