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