001: /*
002: * All content copyright (c) 2003-2006 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 EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
008: import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
009:
010: import com.tc.object.config.ConfigVisitor;
011: import com.tc.object.config.DSOClientConfigHelper;
012: import com.tc.object.config.TransparencyClassSpec;
013: import com.tc.object.config.spec.CyclicBarrierSpec;
014: import com.tc.object.config.spec.SynchronizedIntSpec;
015: import com.tc.simulator.app.ApplicationConfig;
016: import com.tc.simulator.listener.ListenerProvider;
017: import com.tctest.runner.AbstractTransparentApp;
018:
019: import java.util.Arrays;
020:
021: public class DistributedMethodCallTestApp extends
022: AbstractTransparentApp {
023:
024: private SharedModel model = new SharedModel();
025: private final CyclicBarrier sharedBarrier = new CyclicBarrier(
026: getParticipantCount());
027: private final CyclicBarrier sharedBarrier2 = new CyclicBarrier(
028: getParticipantCount());
029:
030: public DistributedMethodCallTestApp(String appId,
031: ApplicationConfig cfg, ListenerProvider listenerProvider) {
032: super (appId, cfg, listenerProvider);
033: }
034:
035: public void run() {
036: try {
037: runTest();
038: runTestWithNulls();
039: runTestNested();
040: runTestNonVoid();
041: runTestWithParamChange();
042: // runTestWithSynchAndNested();
043: } catch (Throwable e) {
044: notifyError(e);
045: }
046: }
047:
048: private void runTest() throws Throwable {
049: final boolean callInitiator = sharedBarrier.barrier() == 0;
050:
051: if (callInitiator) {
052: model.callCount.set(0);
053: synchronized (model) {
054: FooObject[][] foos = makeFooArray();
055: int[][][] ints = makeIntArray();
056: model
057: .addObject(new FooObject(), 1, 2, foos, ints,
058: true);
059: }
060: }
061: sharedBarrier.barrier();
062: final int actual = model.callCount.get();
063: if (actual != getParticipantCount()) {
064: notifyError("Unexpected call count: expected="
065: + getParticipantCount() + ", actual=" + actual);
066: }
067: }
068:
069: private void runTestWithParamChange() throws Throwable {
070: final boolean callInitiator = sharedBarrier.barrier() == 0;
071:
072: if (callInitiator) {
073: model.callCount.set(0);
074: synchronized (model) {
075: FooObject[][] foos = makeFooArray();
076: int[][][] ints = makeIntArray();
077: model.addObjectWithParamChange(new FooObject(), 1, 2,
078: foos, ints, true);
079: }
080: }
081: sharedBarrier.barrier();
082: final int actual = model.callCount.get();
083: if (actual != getParticipantCount()) {
084: notifyError("Unexpected call count: expected="
085: + getParticipantCount() + ", actual=" + actual);
086: }
087: }
088:
089: private void runTestNonVoid() throws Throwable {
090: final boolean callInitiator = sharedBarrier.barrier() == 0;
091:
092: if (callInitiator) {
093: model.callCount.set(0);
094: synchronized (model) {
095: FooObject[][] foos = makeFooArray();
096: int[][][] ints = makeIntArray();
097: model.addObjectNonVoid(new FooObject(), 1, 2, foos,
098: ints, true);
099: }
100: }
101: sharedBarrier.barrier();
102: final int actual = model.callCount.get();
103: if (actual != getParticipantCount()) {
104: notifyError("Unexpected call count: expected="
105: + getParticipantCount() + ", actual=" + actual);
106: }
107: }
108:
109: private void runTestNested() throws Throwable {
110: final boolean callInitiator = sharedBarrier.barrier() == 0;
111:
112: if (callInitiator) {
113: model.callCount.set(0);
114: synchronized (model) {
115: FooObject[][] foos = makeFooArray();
116: int[][][] ints = makeIntArray();
117: model.addObjectNested(new FooObject(), 1, 2, foos,
118: ints, true);
119: }
120: }
121: sharedBarrier.barrier();
122: final int actual = model.callCount.get();
123: if (actual != getParticipantCount()) {
124: notifyError("Unexpected call count: expected="
125: + getParticipantCount() + ", actual=" + actual);
126: }
127: }
128:
129: private void runTestWithNulls() throws Throwable {
130: final boolean callInitiator = sharedBarrier.barrier() == 0;
131:
132: if (callInitiator) {
133: model.callCount.set(0);
134: synchronized (model) {
135: model.addObjectWithNulls(null, 1, 2, null, null, true);
136: }
137: }
138: sharedBarrier.barrier();
139: final int actual = model.callCount.get();
140: if (actual != getParticipantCount()) {
141: notifyError("Unexpected call count: expected="
142: + getParticipantCount() + ", actual=" + actual);
143: }
144: }
145:
146: private static int[][][] makeIntArray() {
147: int[][][] ints = new int[6][8][9];
148: int count = 0;
149: for (int i = 0; i < ints.length; i++) {
150: int[][] array1 = ints[i];
151: for (int j = 0; j < array1.length; j++) {
152: int[] array2 = array1[j];
153: for (int k = 0; k < array2.length; k++) {
154: array2[k] = count++;
155: }
156: }
157: }
158: return ints;
159: }
160:
161: private static FooObject[][] makeFooArray() {
162: FooObject[][] foos = new FooObject[2][3];
163: for (int i = 0; i < foos.length; i++) {
164: Arrays.fill(foos[i], new FooObject());
165: }
166: return foos;
167: }
168:
169: public class SharedModel {
170: public final SynchronizedInt callCount = new SynchronizedInt(0);
171:
172: public synchronized void addObjectSynched(Object obj, int i,
173: double d, FooObject[][] foos, int[][][] ints, boolean b)
174: throws Throwable {
175: this .addObjectSynched(obj, i, d, foos, ints, b);
176: }
177:
178: public String addObjectNonVoid(Object obj, int i, double d,
179: FooObject[][] foos, int[][][] ints, boolean b)
180: throws Throwable {
181: addObject(obj, i, d, foos, ints, b);
182: return new String("A-OK");
183: }
184:
185: public void addObject(Object obj, int i, double d,
186: FooObject[][] foos, int[][][] ints, boolean b)
187: throws Throwable {
188: callCount.increment();
189: // Everything in the "foos" array should be non-null
190: for (int index = 0; index < foos.length; index++) {
191: FooObject[] array = foos[index];
192: for (int j = 0; j < array.length; j++) {
193: FooObject foo = array[j];
194: if (foo == null)
195: notifyError("foo == null");
196: }
197: }
198:
199: // access all the "ints"
200: int count = 0;
201: for (int index = 0; index < ints.length; index++) {
202: int[][] array1 = ints[index];
203: for (int j = 0; j < array1.length; j++) {
204: int[] array2 = array1[j];
205: for (int k = 0; k < array2.length; k++) {
206: int val = array2[k];
207: if (count++ != val)
208: notifyError("count ++ != val");
209: }
210: }
211: }
212:
213: checkLiteralParams(i, d, b);
214: sharedBarrier2.barrier();
215: }
216:
217: public void addObjectWithParamChange(Object obj, int i,
218: double d, FooObject[][] foos, int[][][] ints, boolean b)
219: throws Throwable {
220: callCount.increment();
221: // Everything in the "foos" array should be non-null
222: for (int index = 0; index < foos.length; index++) {
223: FooObject[] array = foos[index];
224: for (int j = 0; j < array.length; j++) {
225: FooObject foo = array[j];
226: if (foo == null)
227: notifyError("foo == null");
228: }
229: }
230:
231: // access all the "ints"
232: int count = 0;
233: for (int index = 0; index < ints.length; index++) {
234: int[][] array1 = ints[index];
235: for (int j = 0; j < array1.length; j++) {
236: int[] array2 = array1[j];
237: for (int k = 0; k < array2.length; k++) {
238: int val = array2[k];
239: if (count++ != val)
240: notifyError("count ++ != val");
241: }
242: }
243: }
244: checkLiteralParams(i, d, b);
245: // now re-assign all params...
246: obj = null;
247: i = -777;
248: foos = null;
249: ints = null;
250: b = !b;
251: sharedBarrier2.barrier();
252: }
253:
254: public void addObjectWithNulls(Object obj, int i, double d,
255: FooObject[][] foos, int[][][] ints, boolean b)
256: throws Throwable {
257: callCount.increment();
258: // all params should be nulls
259: checkReferenceParams(obj, foos, ints, true);
260: checkLiteralParams(i, d, b);
261: sharedBarrier2.barrier();
262: }
263:
264: public void addObjectNested(Object obj, int i, double d,
265: FooObject[][] foos, int[][][] ints, boolean b)
266: throws Throwable {
267: addObject(obj, i, d, foos, ints, b);
268: }
269:
270: private void checkLiteralParams(int i, double d, boolean b) {
271: if (i != 1 || d != 2 || !b) {
272: System.out.println("Invalid parameters: i:" + i + " d:"
273: + d + " b:" + b);
274: notifyError("Invalid parameters: i:" + i + " d:" + d
275: + " b:" + b);
276: }
277: }
278:
279: private void checkReferenceParams(Object o, FooObject[][] foos,
280: int[][][] ints, boolean nullExpected) {
281: checkNull(o, nullExpected);
282: checkNull(foos, nullExpected);
283: checkNull(ints, nullExpected);
284: }
285:
286: private void checkNull(Object o, boolean nullExpected) {
287: final boolean isNull = o == null;
288: if (isNull != nullExpected)
289: notifyError("Wrong parameter value: null is expected, actual = "
290: + o);
291: }
292: }
293:
294: public static void visitL1DSOConfig(ConfigVisitor visitor,
295: DSOClientConfigHelper config) {
296: try {
297: new CyclicBarrierSpec().visit(visitor, config);
298: new SynchronizedIntSpec().visit(visitor, config);
299:
300: TransparencyClassSpec spec = config
301: .getOrCreateSpec(FooObject.class.getName());
302: String testClassName = DistributedMethodCallTestApp.class
303: .getName();
304: spec = config.getOrCreateSpec(testClassName);
305: spec.addTransient("callInitiator");
306: spec.addRoot("model", "model");
307: spec.addRoot("sharedStuff", "sharedStuff");
308: spec.addRoot("sharedBarrier", "sharedBarrier");
309: spec.addRoot("sharedBarrier2", "sharedBarrier2");
310: String methodExpression = "* " + testClassName + "*.*(..)";
311: config.addWriteAutolock(methodExpression);
312: // methodExpression = "* " + DistributedMethodCallTestApp.SharedModel.class.getName() + "*.*(..)";
313: // config.addWriteAutolock(methodExpression);
314:
315: spec = config.getOrCreateSpec(SharedModel.class.getName());
316: spec
317: .addDistributedMethodCall(
318: "addObjectNonVoid",
319: "(Ljava/lang/Object;ID[[Lcom/tctest/FooObject;[[[IZ)java/lang/String;",
320: true);
321: spec
322: .addDistributedMethodCall(
323: "addObjectWithNulls",
324: "(Ljava/lang/Object;ID[[Lcom/tctest/FooObject;[[[IZ)V",
325: true);
326: spec
327: .addDistributedMethodCall(
328: "addObjectWithParamChange",
329: "(Ljava/lang/Object;ID[[Lcom/tctest/FooObject;[[[IZ)V",
330: true);
331: spec
332: .addDistributedMethodCall(
333: "addObjectSynched",
334: "(Ljava/lang/Object;ID[[Lcom/tctest/FooObject;[[[IZ)V",
335: true);
336: spec
337: .addDistributedMethodCall(
338: "addObjectNested",
339: "(Ljava/lang/Object;ID[[Lcom/tctest/FooObject;[[[IZ)V",
340: true);
341: spec
342: .addDistributedMethodCall(
343: "addObject",
344: "(Ljava/lang/Object;ID[[Lcom/tctest/FooObject;[[[IZ)V",
345: true);
346: } catch (Exception e) {
347: throw new AssertionError(e);
348: }
349: }
350: }
|