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.

WeaveTestCase.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  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. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.bcel;
  13. import java.io.*;
  14. import java.util.*;
  15. import junit.framework.*;
  16. import org.aspectj.apache.bcel.Constants;
  17. import org.aspectj.apache.bcel.generic.*;
  18. import org.aspectj.weaver.*;
  19. import org.aspectj.weaver.patterns.*;
  20. import org.aspectj.testing.util.TestUtil;
  21. import org.aspectj.util.FileUtil;
  22. public abstract class WeaveTestCase extends TestCase {
  23. public boolean regenerate = false;
  24. public boolean runTests = true;
  25. public boolean behave15 = false;
  26. File outDir;
  27. String outDirPath;
  28. public BcelWorld world = new BcelWorld();
  29. {
  30. world.addPath(classDir);
  31. // Some of the tests in here rely on comparing output from dumping the delegates - if
  32. // we are using ASM delegates we don't know the names of parameters (they are irrelevant...)
  33. // and are missing from the dumping of asm delegates. This switch ensures we
  34. // continue to use BCEL for these tests.
  35. // world.setFastDelegateSupport(false);
  36. }
  37. public WeaveTestCase(String name) {
  38. super(name);
  39. }
  40. public void setUp() {
  41. outDir = BcweaverTests.getOutdir();
  42. outDirPath = outDir.getAbsolutePath();
  43. }
  44. public void tearDown() throws Exception {
  45. super.tearDown();
  46. BcweaverTests.removeOutDir();
  47. outDir = null;
  48. outDirPath = null;
  49. }
  50. public static InstructionList getAdviceTag(BcelShadow shadow, String where) {
  51. String methodName =
  52. "ajc_" + where + "_" + shadow.getKind().toLegalJavaIdentifier();
  53. InstructionFactory fact = shadow.getFactory();
  54. InvokeInstruction il =
  55. fact.createInvoke("Aspect", methodName, Type.VOID, new Type[] {
  56. }, Constants.INVOKESTATIC);
  57. return new InstructionList(il);
  58. }
  59. public void weaveTest(String name, String outName, ShadowMunger planner) throws IOException {
  60. List l = new ArrayList(1);
  61. l.add(planner);
  62. weaveTest(name, outName, l);
  63. }
  64. //static String classDir = "../weaver/bin";
  65. static String classDir = BcweaverTests.TESTDATA_PATH + File.separator + "bin";
  66. public void weaveTest(String name, String outName, List planners) throws IOException {
  67. BcelWeaver weaver = new BcelWeaver(world);
  68. try {
  69. if (behave15) world.setBehaveInJava5Way(true);
  70. UnwovenClassFile classFile = makeUnwovenClassFile(classDir, name, outDirPath);
  71. weaver.addClassFile(classFile);
  72. weaver.setShadowMungers(planners);
  73. weaveTestInner(weaver, classFile, name, outName);
  74. } finally {
  75. if (behave15) world.setBehaveInJava5Way(false);
  76. }
  77. }
  78. protected void weaveTestInner(
  79. BcelWeaver weaver,
  80. UnwovenClassFile classFile,
  81. String name,
  82. String outName)
  83. throws IOException
  84. {
  85. //int preErrors = currentResult.errorCount();
  86. BcelObjectType classType =
  87. BcelWorld.getBcelObjectType(world.resolve(classFile.getClassName()));
  88. LazyClassGen gen = weaver.weave(classFile, classType);
  89. if (gen == null) {
  90. // we didn't do any weaving, but let's make a gen anyway
  91. gen = classType.getLazyClassGen(); //new LazyClassGen(classType);
  92. }
  93. try {
  94. checkClass(gen, outDirPath, outName + ".txt");
  95. if (runTests) {
  96. System.out.println(
  97. "*******RUNNING: " + outName + " " + name + " *******");
  98. TestUtil.runMain(makeClassPath(outDirPath), name);
  99. }
  100. } catch (Error e) {
  101. System.err.println("Comparing to " + outName + ".txt");
  102. gen.print(System.err);
  103. throw e;
  104. } catch (RuntimeException e) {
  105. gen.print(System.err);
  106. throw e;
  107. }
  108. }
  109. public String makeClassPath(String outDir) {
  110. return outDir
  111. + File.pathSeparator
  112. + getTraceJar()
  113. + File.pathSeparator
  114. + classDir
  115. + File.pathSeparator
  116. + System.getProperty("java.class.path");
  117. }
  118. /** '/' in the name indicates the location of the class
  119. */
  120. public static UnwovenClassFile makeUnwovenClassFile(
  121. String classDir,
  122. String name,
  123. String outDir) throws IOException {
  124. File outFile = new File(outDir, name+".class");
  125. if (classDir.endsWith(".jar")) {
  126. String fname = name+".class";
  127. UnwovenClassFile ret =
  128. new UnwovenClassFile(outFile.getAbsolutePath(),
  129. FileUtil.readAsByteArray(FileUtil.getStreamFromZip(classDir, fname)));
  130. return ret;
  131. } else {
  132. File inFile = new File(classDir, name+".class");
  133. return new UnwovenClassFile(outFile.getAbsolutePath(), FileUtil.readAsByteArray(inFile));
  134. }
  135. }
  136. public void checkClass(LazyClassGen gen, String outDir, String expectedFile) throws IOException {
  137. if (regenerate) genClass(gen, outDir, expectedFile);
  138. else realCheckClass(gen, outDir, expectedFile);
  139. }
  140. static final File TESTDATA_DIR = new File(BcweaverTests.TESTDATA_PATH);
  141. void genClass(LazyClassGen gen, String outDir, String expectedFile) throws IOException {
  142. //ClassGen b = getJavaClass(outDir, className);
  143. FileOutputStream out = new FileOutputStream(new File(TESTDATA_DIR, expectedFile));
  144. PrintStream ps = new PrintStream(out);
  145. gen.print(ps);
  146. ps.flush();
  147. }
  148. void realCheckClass(LazyClassGen gen, String outDir, String expectedFile) throws IOException {
  149. TestUtil.assertMultiLineStringEquals(expectedFile/*"classes"*/,
  150. FileUtil.readAsString(new File(TESTDATA_DIR, expectedFile)),
  151. gen.toLongString());
  152. }
  153. // ----
  154. public ShadowMunger makeConcreteAdvice(String mungerString) {
  155. return makeConcreteAdvice(mungerString, 0, null);
  156. }
  157. public ShadowMunger makeConcreteAdvice(String mungerString, int extraArgFlag) {
  158. return makeConcreteAdvice(mungerString, extraArgFlag, null);
  159. }
  160. protected ShadowMunger makeConcreteAdvice(String mungerString, int extraArgFlag, PerClause perClause) {
  161. Advice myMunger =
  162. TestUtils.shadowMunger(world,mungerString, extraArgFlag);
  163. // PerSingleton s = new PerSingleton();
  164. // s.concretize(world.resolve("Aspect"));
  165. //System.err.println(((KindedPointcut)myMunger.getPointcut().getPointcut()).getKind());
  166. Advice cm = (Advice) myMunger.concretize(myMunger.getDeclaringAspect().resolve(world),
  167. world, perClause);
  168. return cm;
  169. }
  170. public ShadowMunger makeAdviceField(String kind, String extraArgType) {
  171. return makeConcreteAdvice(
  172. kind
  173. + "(): get(* *.*) -> static void Aspect.ajc_"
  174. + kind
  175. + "_field_get("
  176. + extraArgType
  177. + ")",
  178. 1);
  179. }
  180. public List makeAdviceAll(String kind, boolean matchOnlyPrintln) {
  181. List ret = new ArrayList();
  182. if (matchOnlyPrintln) {
  183. ret.add(
  184. makeConcreteAdvice(
  185. kind
  186. + "(): call(* *.println(..)) -> static void Aspect.ajc_"
  187. + kind
  188. + "_method_execution()"));
  189. } else {
  190. ret.add(
  191. makeConcreteAdvice(
  192. kind
  193. + "(): call(* *.*(..)) -> static void Aspect.ajc_"
  194. + kind
  195. + "_method_call()"));
  196. ret.add(
  197. makeConcreteAdvice(
  198. kind
  199. + "(): call(*.new(..)) -> static void Aspect.ajc_"
  200. + kind
  201. + "_constructor_call()"));
  202. ret.add(
  203. makeConcreteAdvice(
  204. kind
  205. + "(): execution(* *.*(..)) -> static void Aspect.ajc_"
  206. + kind
  207. + "_method_execution()"));
  208. ret.add(
  209. makeConcreteAdvice(
  210. kind
  211. + "(): execution(*.new(..)) -> static void Aspect.ajc_"
  212. + kind
  213. + "_constructor_execution()"));
  214. // ret.add(
  215. // makeConcreteMunger(
  216. // kind
  217. // + "(): staticinitialization(*) -> static void Aspect.ajc_"
  218. // + kind
  219. // + "_staticinitialization()"));
  220. ret.add(
  221. makeConcreteAdvice(
  222. kind + "(): get(* *.*) -> static void Aspect.ajc_" + kind + "_field_get()"));
  223. // ret.add(
  224. // makeConcreteMunger(
  225. // kind + "(): set(* *.*) -> static void Aspect.ajc_" + kind + "_field_set()"));
  226. // XXX no test for advice execution, staticInitialization or (god help us) preInitialization
  227. }
  228. return ret;
  229. }
  230. public List makeAdviceAll(final String kind) {
  231. return makeAdviceAll(kind, false);
  232. }
  233. public Pointcut makePointcutAll() {
  234. return makeConcretePointcut("get(* *.*) || call(* *.*(..)) || execution(* *.*(..)) || call(*.new(..)) || execution(*.new(..))");
  235. }
  236. public Pointcut makePointcutNoZeroArg() {
  237. return makeConcretePointcut("call(* *.*(*, ..)) || execution(* *.*(*, ..)) || call(*.new(*, ..)) || execution(*.new(*, ..))");
  238. }
  239. public Pointcut makePointcutPrintln() {
  240. return makeConcretePointcut("call(* *.println(..))");
  241. }
  242. public Pointcut makeConcretePointcut(String s) {
  243. return makeResolvedPointcut(s).concretize(null, null, 0);
  244. }
  245. public Pointcut makeResolvedPointcut(String s) {
  246. Pointcut pointcut0 = Pointcut.fromString(s);
  247. return pointcut0.resolve(new SimpleScope(world, FormalBinding.NONE));
  248. }
  249. // ----
  250. public String[] getStandardTargets() {
  251. return new String[] {"HelloWorld", "FancyHelloWorld"};
  252. }
  253. public String getTraceJar() {
  254. return BcweaverTests.TESTDATA_PATH + "/tracing.jar";
  255. }
  256. // ----
  257. protected void weaveTest(
  258. String[] inClassNames,
  259. String outKind,
  260. ShadowMunger patternMunger) throws IOException {
  261. for (int i = 0; i < inClassNames.length; i++) {
  262. String inFileName = inClassNames[i];
  263. weaveTest(inFileName, outKind + inFileName, patternMunger);
  264. }
  265. }
  266. protected void weaveTest(
  267. String[] inClassNames,
  268. String outKind,
  269. List patternMungers) throws IOException {
  270. for (int i = 0; i < inClassNames.length; i++) {
  271. String inFileName = inClassNames[i];
  272. weaveTest(inFileName, outKind + inFileName, patternMungers);
  273. }
  274. }
  275. protected List addLexicalOrder(List l) {
  276. int i = 10;
  277. for (Iterator iter = l.iterator(); iter.hasNext();) {
  278. Advice element = (Advice) iter.next();
  279. element.setLexicalPosition(i+=10);
  280. }
  281. return l;
  282. }
  283. //XXX cut-and-paster from IdWeaveTestCase
  284. public void checkShadowSet(List l, String[] ss) {
  285. outer:
  286. for (int i = 0, len = ss.length; i < len; i++) {
  287. //inner:
  288. for (Iterator j = l.iterator(); j.hasNext(); ) {
  289. BcelShadow shadow = (BcelShadow) j.next();
  290. String shadowString = shadow.toString();
  291. if (shadowString.equals(ss[i])) {
  292. j.remove();
  293. continue outer;
  294. }
  295. }
  296. assertTrue("didn't find " + ss[i] + " in " + l, false);
  297. }
  298. assertTrue("too many things in " + l, l.size() == 0);
  299. }
  300. }