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

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