KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tctest > NewObjectCreationRaceTest


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tctest;
5
6 import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
7 import EDU.oswego.cs.dl.util.concurrent.SynchronizedRef;
8
9 import com.tc.object.config.ConfigVisitor;
10 import com.tc.object.config.DSOClientConfigHelper;
11 import com.tc.object.config.TransparencyClassSpec;
12 import com.tc.object.config.spec.CyclicBarrierSpec;
13 import com.tc.simulator.app.ApplicationConfig;
14 import com.tc.simulator.listener.ListenerProvider;
15 import com.tc.util.Assert;
16 import com.tctest.runner.AbstractErrorCatchingTransparentApp;
17
18 import java.util.HashMap JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Map.Entry;
22
23 public class NewObjectCreationRaceTest extends TransparentTestBase {
24
25   private static final int NODE_COUNT = 3;
26
27   public void setUp() throws Exception JavaDoc {
28     super.setUp();
29     getTransparentAppConfig().setClientCount(NODE_COUNT).setIntensity(1);
30     initializeTestRunner();
31   }
32
33   protected Class JavaDoc getApplicationClass() {
34     return NewObjectCreationRaceTestApp.class;
35   }
36
37   public static class NewObjectCreationRaceTestApp extends AbstractErrorCatchingTransparentApp {
38
39     // NOTE: it is very important to NOT reference
40
// this root in the "fault" nodes, until after it has the new object in it
41
private Map JavaDoc root;
42
43     private final CyclicBarrier barrier;
44
45     public NewObjectCreationRaceTestApp(String JavaDoc appId, ApplicationConfig cfg, ListenerProvider listenerProvider) {
46       super(appId, cfg, listenerProvider);
47
48       if (getParticipantCount() < 2) { throw new AssertionError JavaDoc("need at least two nodes for this test to work"); }
49
50       barrier = new CyclicBarrier(getParticipantCount());
51     }
52
53     protected void runTest() throws Throwable JavaDoc {
54       int n = barrier.barrier();
55
56       if (n == 0) {
57         runCreateNode();
58       } else {
59         runFaultNode();
60       }
61     }
62
63     private void runFaultNode() throws Exception JavaDoc {
64       barrier.barrier();
65
66       final Map JavaDoc faultedRoot;
67
68       // fault the root under the same lock it was modified under
69
// this avoids a ConcurrentModificationException
70
synchronized (barrier) {
71         faultedRoot = root;
72       }
73
74       for (Iterator JavaDoc i = faultedRoot.entrySet().iterator(); i.hasNext();) {
75         Map.Entry JavaDoc entry = (Entry) i.next();
76         Object JavaDoc key = entry.getKey();
77         System.out.println(key);
78         Object JavaDoc value = entry.getValue();
79         System.out.println(value);
80
81         if (value instanceof Ref) {
82           Object JavaDoc ref = ((Ref) value).getRef();
83           System.out.println(ref);
84         }
85       }
86
87       // unblock the create node
88
barrier.barrier();
89
90       // wait for the create node to commit it's change
91
barrier.barrier();
92
93       // make sure the delta is in there
94
synchronized (faultedRoot) {
95         Object JavaDoc o = faultedRoot.get("delta");
96         Assert.assertEquals("non-null", o);
97         Assert.assertEquals(5, faultedRoot.size());
98       }
99     }
100
101     private void runCreateNode() throws Throwable JavaDoc {
102       final SynchronizedRef error = new SynchronizedRef(null);
103
104       // create root in this node only
105
root = new HashMap JavaDoc();
106
107       final Object JavaDoc newObj = new Object JavaDoc();
108       final Ref newRefToOtherNewObject = new Ref(new Object JavaDoc());
109
110       synchronized (root) {
111         root.put("delta", null);
112         root.put("new object", newObj);
113         root.put("new ref to new obj", newRefToOtherNewObject);
114
115         Runnable JavaDoc otherTxn = new Runnable JavaDoc() {
116           public void run() {
117             try {
118               synchronized (barrier) {
119                 root.put("ref to new with ref to created", new Ref(newObj));
120                 root.put("ref to created with ref to created", newRefToOtherNewObject);
121               }
122             } catch (Throwable JavaDoc err) {
123               error.set(err);
124             }
125           }
126         };
127
128         Thread JavaDoc t1 = new Thread JavaDoc(otherTxn);
129         t1.start();
130         t1.join();
131
132         checkError(error);
133
134         // unblock the "fault" nodes. Need to do this in another thread so that the
135
// TXN the current thread is in doesn't commit()
136
Runnable JavaDoc doBarrier = new Runnable JavaDoc() {
137           public void run() {
138             try {
139               barrier.barrier();
140             } catch (Throwable JavaDoc err) {
141               error.set(err);
142             }
143           }
144         };
145         Thread JavaDoc t2 = new Thread JavaDoc(doBarrier);
146         t2.start();
147         t2.join();
148
149         checkError(error);
150
151         // block at least until the other node(s) cause the problematic fault. This also needs to be done in another
152
// thread so that this thread's TXN does not commit
153
Thread JavaDoc t3 = new Thread JavaDoc(doBarrier);
154         t3.start();
155         t3.join();
156
157         checkError(error);
158
159         // create a change (ie. delta DNA) in the original transaction
160
root.put("delta", "non-null");
161
162         barrier.barrier();
163       }
164
165     }
166
167     private void checkError(SynchronizedRef error) throws Throwable JavaDoc {
168       Throwable JavaDoc t = (Throwable JavaDoc) error.get();
169       if (t != null) { throw t; }
170     }
171
172     public static void visitL1DSOConfig(ConfigVisitor visitor, DSOClientConfigHelper config) {
173       new CyclicBarrierSpec().visit(visitor, config);
174
175       String JavaDoc testClass;
176       TransparencyClassSpec spec;
177       String JavaDoc methodExpression;
178
179       testClass = Ref.class.getName();
180       spec = config.getOrCreateSpec(testClass);
181
182       testClass = NewObjectCreationRaceTest.class.getName();
183       spec = config.getOrCreateSpec(testClass);
184       methodExpression = "* " + testClass + "*.*(..)";
185       config.addWriteAutolock(methodExpression);
186
187       config.addIncludePattern(testClass + "$*");
188
189       testClass = NewObjectCreationRaceTestApp.class.getName();
190       spec = config.getOrCreateSpec(testClass);
191
192       methodExpression = "* " + testClass + "*.*(..)";
193       config.addWriteAutolock(methodExpression);
194       spec.addRoot("barrier", "barrier");
195       spec.addRoot("root", "root");
196     }
197
198   }
199
200   private static class Ref {
201     private final Object JavaDoc ref;
202
203     Ref(Object JavaDoc ref) {
204       this.ref = ref;
205     }
206
207     Object JavaDoc getRef() {
208       return ref;
209     }
210   }
211
212 }
213
Popular Tags