001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tctest;
006:
007: import com.tc.exception.ImplementMe;
008: import com.tc.exception.TCNonPortableObjectError;
009: import com.tc.object.tx.UnlockedSharedObjectException;
010: import com.tc.object.util.ReadOnlyException;
011: import com.tc.simulator.app.ApplicationConfig;
012: import com.tc.simulator.listener.ListenerProvider;
013: import com.tctest.runner.AbstractErrorCatchingTransparentApp;
014:
015: import java.lang.reflect.InvocationHandler;
016: import java.lang.reflect.InvocationTargetException;
017: import java.lang.reflect.Method;
018: import java.lang.reflect.Proxy;
019:
020: public abstract class GenericLocalStateTestApp extends
021: AbstractErrorCatchingTransparentApp {
022:
023: public GenericLocalStateTestApp(String appId,
024: ApplicationConfig cfg, ListenerProvider listenerProvider) {
025: super (appId, cfg, listenerProvider);
026: }
027:
028: protected void runTest() throws Throwable {
029: throw new ImplementMe();
030: }
031:
032: protected void testMutate(Wrapper wrapper, LockMode lockMode,
033: Mutator mutator) throws Throwable {
034: int oldSize = wrapper.size();
035: LockMode curr_lockMode = wrapper.getHandler().getLockMode();
036: boolean gotExpectedException = false;
037: Throwable throwable = null;
038:
039: if (await() == 0) {
040: System.out.println("Mutating: "
041: + wrapper.getObject().getClass().getSimpleName()
042: + " with " + mutator.getClass().getSimpleName()
043: + " with lock " + lockMode);
044: wrapper.getHandler().setLockMode(lockMode);
045: try {
046: mutator.doMutate(wrapper.getProxy());
047: } catch (UnlockedSharedObjectException usoe) {
048: gotExpectedException = lockMode == LockMode.NONE;
049: } catch (ReadOnlyException roe) {
050: gotExpectedException = lockMode == LockMode.READ;
051: } catch (TCNonPortableObjectError ne) {
052: gotExpectedException = lockMode == LockMode.WRITE;
053: } catch (Throwable t) {
054: throwable = t;
055: }
056: }
057:
058: System.out.println("Waiting for mutation to finished...");
059: await();
060: System.out.println("... done await(): gotExpectedException="
061: + gotExpectedException);
062:
063: wrapper.getHandler().setLockMode(curr_lockMode);
064:
065: if (gotExpectedException) {
066: System.out.println("... validating...");
067: validate(oldSize, wrapper, lockMode, mutator);
068: }
069:
070: if (throwable != null) {
071: System.err.println(" ---- ERROR DETECTED --- ");
072: throw throwable;
073: }
074: }
075:
076: protected abstract int await();
077:
078: protected abstract void validate(int oldSize, Wrapper wrapper,
079: LockMode lockMode, Mutator mutator) throws Throwable;
080:
081: static enum LockMode {
082: NONE, READ, WRITE
083: }
084:
085: static class Handler implements InvocationHandler {
086: private final Object o;
087: private LockMode lockMode = LockMode.NONE;
088:
089: public Handler(Object o) {
090: this .o = o;
091: }
092:
093: public LockMode getLockMode() {
094: return lockMode;
095: }
096:
097: public void setLockMode(LockMode mode) {
098: synchronized (this ) {
099: lockMode = mode;
100: }
101: }
102:
103: public Object invoke(Object proxy, Method method, Object[] args)
104: throws Throwable {
105: try {
106: switch (lockMode) {
107: case NONE:
108: return method.invoke(o, args);
109: case READ:
110: return invokeWithReadLock(method, args);
111: case WRITE:
112: return invokeWithWriteLock(method, args);
113: default:
114: throw new RuntimeException("Should'n happen");
115: }
116: } catch (InvocationTargetException e) {
117: throw e.getTargetException();
118: }
119: }
120:
121: private Object invokeWithReadLock(Method method, Object[] args)
122: throws Throwable {
123: synchronized (o) {
124: return method.invoke(o, args);
125: }
126: }
127:
128: private Object invokeWithWriteLock(Method method, Object[] args)
129: throws Throwable {
130: synchronized (o) {
131: return method.invoke(o, args);
132: }
133: }
134: }
135:
136: static interface Wrapper {
137: public Object getObject();
138:
139: public Object getProxy();
140:
141: public Handler getHandler();
142:
143: public int size();
144: }
145:
146: static interface Mutator {
147: public void doMutate(Object o);
148: }
149:
150: static class CollectionWrapper implements Wrapper {
151: private Object object;
152: private Object proxy;
153: private Handler handler;
154:
155: public CollectionWrapper(Class objectClass, Class interfaceClass)
156: throws Exception {
157: object = objectClass.newInstance();
158: handler = new Handler(object);
159: proxy = Proxy.newProxyInstance(getClass().getClassLoader(),
160: new Class[] { interfaceClass }, handler);
161: }
162:
163: public Handler getHandler() {
164: return handler;
165: }
166:
167: public Object getObject() {
168: return object;
169: }
170:
171: public Object getProxy() {
172: return proxy;
173: }
174:
175: public int size() {
176: try {
177: Method method = object.getClass().getMethod("size");
178: return (Integer) method.invoke(object);
179: } catch (Exception e) {
180: e.printStackTrace();
181: throw new RuntimeException(e);
182: }
183: }
184: }
185: }
|