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.tctest;
005:
006: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
007:
008: import com.tc.object.bytecode.ManagerUtil;
009: import com.tc.object.config.ConfigVisitor;
010: import com.tc.object.config.DSOClientConfigHelper;
011: import com.tc.object.config.TransparencyClassSpec;
012: import com.tc.object.config.spec.CyclicBarrierSpec;
013: import com.tc.object.lockmanager.api.LockLevel;
014: import com.tc.simulator.app.ApplicationConfig;
015: import com.tc.simulator.listener.ListenerProvider;
016: import com.tc.util.Assert;
017: import com.tctest.runner.AbstractTransparentApp;
018:
019: import java.sql.Timestamp;
020: import java.util.Date;
021: import java.util.Iterator;
022: import java.util.Map.Entry;
023: import java.util.concurrent.ConcurrentHashMap;
024: import java.util.concurrent.LinkedBlockingQueue;
025:
026: public class JavaUtilConcurrentCloneTestApp extends
027: AbstractTransparentApp {
028:
029: public static final int NODE_COUNT = 2;
030:
031: private MyStuff root;
032: private CyclicBarrier barrier = new CyclicBarrier(NODE_COUNT);
033: private int nodeCount[] = new int[1];
034:
035: public JavaUtilConcurrentCloneTestApp(String appId,
036: ApplicationConfig cfg, ListenerProvider listenerProvider) {
037: super (appId, cfg, listenerProvider);
038: }
039:
040: public void run() {
041: try {
042: int myId = 0;
043: synchronized (nodeCount) {
044: myId = nodeCount[0]++;
045: }
046: MyStuff copy = null;
047: if (myId == 0) {
048: MyStuff s = new MyStuff(null);
049: s.linkedBlockingQueue = new LinkedBlockingQueue();
050: s.linkedBlockingQueue.put("first element");
051:
052: s.map = new ConcurrentHashMap();
053: MapInnerObject innerObject = new MapInnerObject(true);
054: MapObject mapObject = new MapObject(10, innerObject);
055: //s.map.put(mapObject, mapObject);
056: s.map.put(s, s);
057:
058: s.linkedBlockingQueue.put(s.map);
059: s.one = 2;
060: s.date = new Date();
061: s.myStuffArray = new MyStuff[10];
062: s.shortArray = new short[200];
063: s.myStuffArray[3] = s;
064: s.myStuffArray[9] = new MyStuff(null);
065: s.shortArray[5] = 4;
066:
067: root = new MyStuff(s);
068:
069: synchronized (root) {
070: s.obj1 = root;
071: root.one = 1;
072: root.date = s.date;
073: root.mapObject = mapObject;
074: }
075: ManagerUtil.optimisticBegin();
076: copy = (MyStuff) ManagerUtil.deepCopy(root);
077:
078: Assert.eval(copy != root);
079: Assert.eval(copy.obj1 != root.obj1);
080:
081: System.out.println("Root:" + root);
082: System.out.println("Root obj:" + root.obj1 + " one:"
083: + root.one);
084: System.out.println("sub Root obj:" + root.obj1.obj1
085: + " one:" + root.obj1.one);
086:
087: System.out.println("Copy:" + copy);
088: System.out.println("Copy obj:" + copy.obj1 + " one:"
089: + copy.one);
090: System.out.println("sub Copy obj:" + copy.obj1.obj1
091: + " one:" + copy.obj1.one);
092:
093: Assert.eval(copy == copy.obj1.obj1);
094: Assert.eval(copy.inner != root.inner);
095: Assert.eval(copy.inner != null);
096: Assert.eval(copy.one == 1);
097: Assert.eval(copy.obj1.one == 2);
098: Assert.eval(copy.obj1.map != root.obj1.map);
099: Assert.eval(copy.obj1.myStuffArray[3] == copy.obj1);
100: Assert.eval(copy.obj1.myStuffArray[4] == null);
101: Assert.eval(copy.obj1.myStuffArray[2] == null);
102: Assert
103: .eval(copy.obj1.myStuffArray != root.obj1.myStuffArray);
104:
105: Assert.eval(copy.obj1.shortArray[4] != 4);
106: Assert.eval(copy.obj1.shortArray[5] == 4);
107: Assert.eval(copy.obj1.shortArray[6] != 4);
108: Assert
109: .eval(copy.obj1.shortArray != root.obj1.shortArray);
110:
111: int size = 0;
112: for (Iterator i = copy.obj1.map.entrySet().iterator(); i
113: .hasNext();) {
114: size++;
115: Entry e = (Entry) i.next();
116: Assert.eval(e.getValue() == copy.obj1);
117: Assert.eval(e.getKey() == copy.obj1);
118: }
119:
120: Assert.eval(size == 1);
121:
122: Assert.eval((copy.obj1.date != root.obj1.date));
123: Assert.eval((copy.obj1.date.equals(root.obj1.date)));
124: Assert.eval(copy.obj1.date == copy.date);
125:
126: Assert
127: .eval(copy.obj1.linkedBlockingQueue.size() == root.obj1.linkedBlockingQueue
128: .size());
129: Assert.eval(copy.obj1.linkedBlockingQueue.poll()
130: .equals("first element"));
131: Assert
132: .eval(copy.obj1.linkedBlockingQueue.poll() == copy.obj1.map);
133:
134: Date d = new Date();
135: copy.obj1.map.put("date", d);
136: copy.obj1.map.put(copy, d);
137: copy.date = d;
138: copy.one = 500;
139:
140: Assert.eval(root.date != d);
141: Assert.eval(!root.obj1.map.containsKey("date"));
142: Assert.eval(root.one != 500);
143:
144: ManagerUtil.beginLock("test", LockLevel.WRITE);
145: ManagerUtil.optimisticCommit();
146: ManagerUtil.commitLock("test");
147:
148: Assert.eval(root.date == d);
149: Assert.eval(root.one == 500);
150: }
151: System.out.println("NODE:" + myId + " is about to enter");
152: barrier();
153: if (myId == 0) {
154: ManagerUtil.optimisticBegin();
155: synchronized ("test") {
156: copy = (MyStuff) ManagerUtil.deepCopy(root);
157: }
158: }
159: barrier();
160: if (myId == 0) {
161: copy.obj1.one = 250;
162: copy.obj1.map.put("steve", "steve");
163: copy.obj1.map.put("doh", copy);
164: Assert.eval(copy != null);
165: copy.obj1.myStuffArray[7] = new MyStuff(null);
166: copy.obj1.myStuffArray[7].one = 7;
167: copy.obj1.myStuffArray[3] = copy;
168: }
169: barrier();
170: if (myId == 1) {
171: synchronized ("test") {
172: root.obj1.one = 150;
173: }
174: }
175: barrier();
176: if (myId == 0) {
177: ManagerUtil.beginLock("test", LockLevel.WRITE);
178: ManagerUtil.optimisticCommit();
179: ManagerUtil.commitLock("test");
180: }
181: barrier();
182: System.out.println("NODE:" + myId + " is about to exit");
183: synchronized ("test") {
184: System.out.println("NODE:" + myId + " Value:"
185: + root.obj1.one);
186: Assert.eval(root.obj1.one == 250);
187: Assert.eval(root.obj1.myStuffArray[7] != null);
188: Assert.eval(root.obj1.myStuffArray[7].one == 7);
189: }
190: } catch (Throwable t) {
191: notifyError(t);
192: }
193: }
194:
195: private void barrier() {
196:
197: try {
198: barrier.barrier();
199: } catch (InterruptedException ie) {
200: throw new AssertionError();
201: }
202: }
203:
204: public static void visitL1DSOConfig(ConfigVisitor visitor,
205: DSOClientConfigHelper config) {
206: String testClass = JavaUtilConcurrentCloneTestApp.class
207: .getName();
208: TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
209: spec.addRoot("barrier", "barrier");
210: spec.addRoot("root", "root");
211: spec.addRoot("nodeCount", "nodeCount");
212: spec = config.getOrCreateSpec(MyStuff.class.getName());
213: spec = config.getOrCreateSpec(MyStuff.MyInner.class.getName());
214: spec = config.getOrCreateSpec(MapObject.class.getName());
215: spec = config.getOrCreateSpec(MapInnerObject.class.getName());
216:
217: String methodExpression = "* " + testClass + "*.*(..)";
218: config.addWriteAutolock(methodExpression);
219: new CyclicBarrierSpec().visit(visitor, config);
220:
221: }
222:
223: private static class MyStuff {
224: public MyStuff obj1;
225: public long one = 1;
226: public LinkedBlockingQueue linkedBlockingQueue;
227: public ConcurrentHashMap map;
228: public Date date;
229: public Timestamp timestamp;
230: public MyStuff[] myStuffArray;
231: public short[] shortArray;
232: public MyInner inner = new MyInner();
233: public MapObject mapObject;
234:
235: public MyStuff(MyStuff stuff) {
236: this .obj1 = stuff;
237: }
238:
239: private class MyInner {
240: public int two;
241: }
242: }
243:
244: private static class MapObject {
245: private int i;
246: private MapInnerObject innerObject;
247:
248: public MapObject(int i, MapInnerObject innerObject) {
249: this .i = i;
250: this .innerObject = innerObject;
251: }
252:
253: public int getI() {
254: return i;
255: }
256:
257: public MapInnerObject getInnerObject() {
258: return innerObject;
259: }
260: }
261:
262: private static class MapInnerObject {
263: private boolean flag;
264:
265: public MapInnerObject(boolean flag) {
266: this .flag = flag;
267: }
268:
269: public boolean isFlag() {
270: return flag;
271: }
272: }
273: }
|