001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.aspectwerkz;
005:
006: import junit.framework.TestCase;
007:
008: import com.tc.aspectwerkz.exception.WrappedRuntimeException;
009:
010: import java.io.File;
011: import java.io.IOException;
012: import java.lang.reflect.Constructor;
013: import java.lang.reflect.Method;
014: import java.net.URL;
015: import java.net.URLClassLoader;
016: import java.util.ArrayList;
017: import java.util.StringTokenizer;
018:
019: /**
020: * Transparently runs TestCase with an embedded online mode Write a JUnit test case and extends WeaverTestCase.
021: *
022: * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
023: */
024: public class WeavedTestCase extends TestCase {
025: /**
026: * the test runner that runs the test thru reflection in a weaving ClassLoader
027: */
028: private static WeaverTestRunner s_runner = new WeaverTestRunner();
029:
030: public WeavedTestCase() {
031: super ();
032: }
033:
034: public WeavedTestCase(String name) {
035: super (name);
036: }
037:
038: /**
039: * Overrides JUnit runBare() to run thru the weaverTestRunner This allow WeaverTestCase to be regular TestCase
040: *
041: * @throws java.lang.Throwable
042: */
043: public void runBare() throws Throwable {
044: s_runner.runTest(this .getClass().getName(), getName());
045: }
046:
047: /**
048: * Callback the regulare JUnit runBare()
049: *
050: * @throws java.lang.Throwable
051: */
052: public void runBareAfterWeaving() throws Throwable {
053: super .runBare();
054: }
055:
056: /**
057: * Allow to run WeaverTestCase thru a weaving ClassLoader
058: */
059: public static class WeaverTestRunner {
060: /**
061: * Weaving classloader
062: */
063: private ClassLoader cl;
064:
065: /**
066: * Build weavin classloader with system class path and ext. classloader as parent
067: */
068: public WeaverTestRunner() {
069: try {
070: String path = System.getProperty("java.class.path");
071: ArrayList paths = new ArrayList();
072: StringTokenizer st = new StringTokenizer(path,
073: File.pathSeparator);
074: while (st.hasMoreTokens()) {
075: paths.add((new File(st.nextToken()))
076: .getCanonicalFile().toURL());
077: }
078: cl = new URLClassLoader((URL[]) paths
079: .toArray(new URL[] {}), ClassLoader
080: .getSystemClassLoader().getParent(), null);
081: } catch (IOException e) {
082: throw new WrappedRuntimeException(e);
083: }
084: }
085:
086: /**
087: * Runs a single test (testXX) Takes care of not using the weaving class loader is online mode or
088: * weavingClassLoader.main() is already used (might fail under JRockit MAPI)
089: *
090: * @param testClassName test class
091: * @param testMethodName test method
092: * @throws java.lang.Throwable
093: */
094: public void runTest(String testClassName, String testMethodName)
095: throws Throwable {
096: // skip test embedded weaving if online mode / weavingClassLoader.main() is already used
097: if ((cl.getClass().getClassLoader() == null)
098: || (cl.getClass().getClassLoader().getClass()
099: .getName().indexOf("hook.impl.Weaving") > 0)) {
100: ;
101: } else {
102: Thread.currentThread().setContextClassLoader(cl); // needed for Aspect loading
103: }
104: Class testClass = Class.forName(testClassName, true, Thread
105: .currentThread().getContextClassLoader());
106:
107: //)cl.loadClass(testClassName);
108: Constructor ctor = null;
109: Object testInstance = null;
110: try {
111: // new junit style
112: ctor = testClass.getConstructor(new Class[] {});
113: testInstance = ctor.newInstance(new Object[] {});
114: Method setNameMethod = testClass.getMethod(
115: "setExpression", new Class[] { String.class });
116: setNameMethod.invoke(testInstance,
117: new Object[] { testMethodName });
118: } catch (NoSuchMethodException e) {
119: ctor = testClass
120: .getConstructor(new Class[] { String.class });
121: testInstance = ctor
122: .newInstance(new Object[] { testMethodName });
123: }
124: Method runAfterWeavingMethod = testClass.getMethod(
125: "runBareAfterWeaving", new Class[] {});
126: runAfterWeavingMethod.invoke(testInstance, new Object[] {});
127: }
128: }
129: }
|