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 com.tc.object.config.ConfigVisitor;
007: import com.tc.object.config.DSOClientConfigHelper;
008: import com.tc.object.config.TransparencyClassSpec;
009: import com.tc.simulator.app.ApplicationConfig;
010: import com.tc.simulator.listener.ListenerProvider;
011: import com.tc.util.Assert;
012: import com.tc.util.concurrent.ThreadUtil;
013: import com.tctest.runner.AbstractTransparentApp;
014:
015: import java.util.ArrayList;
016: import java.util.LinkedList;
017: import java.util.List;
018:
019: public class NestedTransactionApp extends AbstractTransparentApp {
020:
021: private static final String TARGET_CLASS_NAME = "com.tctest.NestedTransactionApp";
022: private static final String TARGET_INNER_CLASS_NAME = "com.tctest.NestedTransactionApp$TestObj";
023:
024: private final static int ACTIONS = 20;
025: public final static int NODE_COUNT = 3;
026:
027: private int myCount;
028: private int totalCount;
029:
030: private final List list1;
031: private List list2 = new ArrayList();
032: private List list3 = new ArrayList();
033:
034: public NestedTransactionApp(String appId, ApplicationConfig cfg,
035: ListenerProvider listenerProvider) {
036: super (appId, cfg, listenerProvider);
037: this .list1 = new LinkedList();
038: this .myCount = ACTIONS;
039: this .totalCount = ACTIONS * NODE_COUNT;
040: }
041:
042: public static void visitL1DSOConfig(ConfigVisitor visitor,
043: DSOClientConfigHelper config) {
044: TransparencyClassSpec spec = config
045: .getOrCreateSpec(TARGET_CLASS_NAME);
046:
047: config.getOrCreateSpec(TARGET_INNER_CLASS_NAME);
048:
049: spec.addRoot("list1", "stuff1");
050: spec.addRoot("list2", "stuff2");
051: spec.addRoot("list3", "stuff3");
052:
053: String methodPattern = "* " + TARGET_CLASS_NAME + ".add1(..)";
054: config.addWriteAutolock(methodPattern);
055:
056: methodPattern = "* " + TARGET_CLASS_NAME + ".add2(..)";
057: config.addWriteAutolock(methodPattern);
058:
059: methodPattern = "* " + TARGET_CLASS_NAME + ".add3(..)";
060: config.addWriteAutolock(methodPattern);
061:
062: methodPattern = "* " + TARGET_CLASS_NAME + ".move(..)";
063: config.addWriteAutolock(methodPattern);
064:
065: methodPattern = "* " + TARGET_CLASS_NAME + ".remove1(..)";
066: config.addWriteAutolock(methodPattern);
067:
068: methodPattern = "* " + TARGET_CLASS_NAME + ".remove2(..)";
069: config.addWriteAutolock(methodPattern);
070:
071: methodPattern = "* " + TARGET_CLASS_NAME + ".finished(..)";
072: config.addWriteAutolock(methodPattern);
073:
074: methodPattern = "* " + TARGET_CLASS_NAME + ".notDone(..)";
075: config.addWriteAutolock(methodPattern);
076:
077: }
078:
079: public void add1(TestObj testObj) {
080: synchronized (list1) {
081: int s = list1.size();
082: list1.add(testObj);
083: Assert.eval(s + 1 == list1.size());
084: // System.out.println("Added1:"+list1.size());
085: }
086: }
087:
088: public void add3(TestObj testObj) {
089: synchronized (list3) {
090: int s = list3.size();
091: list3.add(testObj);
092: Assert.eval(s + 1 == list3.size());
093: // System.out.println("Added1:"+list1.size());
094: }
095: }
096:
097: public void add2(TestObj testObj) {
098: synchronized (list2) {
099: try {
100: int s = list2.size();
101: list2.add(testObj);
102: Assert.eval(s + 1 == list2.size());
103: // System.out.println("Added2:"+list2.size());
104: } catch (Throwable e) {
105: e.printStackTrace();
106: }
107: }
108: }
109:
110: public void move() {
111: synchronized (list1) {
112: synchronized (list2) {
113: try {
114: if (list1.size() > 0) {
115: // System.out.println("Moving from 1 to 2");
116: int s = list1.size();
117: TestObj obj = remove1();
118: // Assert.eval(s - 1 == list1.size());
119: if (s - 1 != list1.size()) {
120: throw new AssertionError("s - 1 ("
121: + (s - 1) + ") != list1.size() ("
122: + list1.size() + ")");
123: }
124: // System.out.println("list1 size:"+list1.size());
125: add2(obj);
126: }
127: } catch (Throwable e) {
128: e.printStackTrace();
129: }
130: }
131: }
132: }
133:
134: public TestObj remove1() {
135: TestObj to = null;
136: try {
137: int s = list1.size();
138: if (s > 0) {
139: to = (TestObj) list1.remove(0);
140: if (s - 1 != list1.size()) {
141: throw new AssertionError("s - 1 (" + (s - 1)
142: + ") != list1.size() (" + list1.size()
143: + ")");
144: }
145: // Assert.eval(s - 1 == list1.size());
146: }
147: } catch (Throwable e) {
148: e.printStackTrace();
149: }
150: return to;
151:
152: }
153:
154: public void run() {
155: add3(new TestObj());
156:
157: for (int i = 0; i < myCount; i++) {
158: add1(new TestObj());
159: }
160:
161: while (notDone()) {
162: ThreadUtil.reallySleep(50);
163: move();
164: }
165: finished();
166: }
167:
168: private void finished() {
169: synchronized (list2) {
170: if (list2.size() != totalCount) {
171: throw new AssertionError("list2.size()=" + list2.size()
172: + ", expected: " + totalCount);
173: }
174: }
175: }
176:
177: private boolean notDone() {
178: synchronized (list2) {
179: if (list2.size() > totalCount - 10)
180: System.err.println("list2.size()=" + list2.size()
181: + " still less than " + totalCount
182: + ". NOT DONE. list1.size()=" + list1.size()
183: + ", list3.size()=" + list3.size());
184: return list2.size() < totalCount;
185: }
186: }
187:
188: private class TestObj {
189: //
190: }
191: }
|