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.config.ConfigVisitor;
009: import com.tc.object.config.DSOClientConfigHelper;
010: import com.tc.object.config.Root;
011: import com.tc.object.config.spec.CyclicBarrierSpec;
012: import com.tc.simulator.app.ApplicationConfig;
013: import com.tc.simulator.listener.ListenerProvider;
014: import com.tc.util.Assert;
015: import com.tctest.runner.AbstractErrorCatchingTransparentApp;
016:
017: import java.util.HashMap;
018: import java.util.Iterator;
019: import java.util.List;
020: import java.util.Map;
021: import java.util.Vector;
022:
023: /**
024: *
025: */
026: public class TransparentVectorTestApp extends
027: AbstractErrorCatchingTransparentApp {
028:
029: public TransparentVectorTestApp(String globalId,
030: ApplicationConfig cfg, ListenerProvider listenerProvider) {
031: super (globalId, cfg, listenerProvider);
032: barrier = new CyclicBarrier(getParticipantCount());
033: }
034:
035: private static final int INITIAL_STAGE = 0;
036: private static final int ADD_COMPLETE_STAGE = 1;
037: private static final int ASSERT_MAX_COUNT_SIZE_STAGE = 2;
038: private static final int REMOVE_COMPLETE_STAGE = 3;
039: private static final int ASSERT_REMOVE_SIZE_STAGE = 4;
040:
041: private final Vector vector = new Vector();
042: // private List subList;
043:
044: private final CyclicBarrier barrier;
045:
046: public void moveToStageAndWait(int stage) {
047: super .moveToStageAndWait(stage);
048: }
049:
050: protected void runTest() throws Throwable {
051: int maxCount = getParticipantCount() * getIntensity();
052: List testObjects = new Vector();
053: moveToStage(INITIAL_STAGE);
054: for (int i = 0; i < getIntensity(); i++) {
055: TestObject to = new TestObject(getApplicationId(), i);
056: testObjects.add(to);
057: synchronized (vector) {
058: int size = vector.size();
059: vector.add(to);
060: Assert.eval(vector.size() == size + 1);
061: }
062: }
063: moveToStageAndWait(ADD_COMPLETE_STAGE);
064:
065: checkSize(maxCount);
066:
067: moveToStageAndWait(ASSERT_MAX_COUNT_SIZE_STAGE);
068: int removeCount = getIntensity() / 2;
069: for (int i = 0; i < removeCount; i++) {
070: synchronized (vector) {
071: int size = vector.size();
072: Object toRemove = testObjects.get(i);
073: boolean wasRemoved = vector.remove(toRemove);
074: if (!wasRemoved) {
075: System.out.println("List:" + vector + " list hash:"
076: + System.identityHashCode(vector));
077: Assert.eval(
078: "Test object should have been removed but wasn't: "
079: + testObjects.get(i), wasRemoved);
080: Assert.eval(vector.size() == size - 1);
081: }
082: }
083: }
084:
085: moveToStageAndWait(REMOVE_COMPLETE_STAGE);
086:
087: checkSize(maxCount - getParticipantCount() * removeCount);
088:
089: moveToStageAndWait(ASSERT_REMOVE_SIZE_STAGE);
090:
091: synchronized (vector) {
092: vector.clear();
093: Assert.eval(vector.size() == 0);
094: }
095:
096: checkSize(0);
097:
098: int num = barrier.barrier();
099:
100: if (num == 0) {
101: synchronized (vector) {
102: vector.setSize(5);
103: }
104: }
105:
106: barrier.barrier();
107:
108: checkSize(5);
109:
110: for (int i = 0; i < 5; i++) {
111: Object val = vector.get(i);
112: if (val != null) {
113: notifyError("Expected null at index " + i
114: + ", but found " + val);
115: return;
116: }
117: }
118:
119: barrier.barrier();
120:
121: // subList = vector.subList(1, 3);
122: //
123: // Assert.assertNotNull(subList);
124: // Assert.assertEquals(2, subList.size());
125:
126: notifyResult(Boolean.TRUE);
127: }
128:
129: private void checkSize(int s) {
130: synchronized (vector) {
131: if (vector.size() != s) {
132: Map res = new HashMap();
133: for (Iterator i = vector.iterator(); i.hasNext();) {
134: TestObject to = (TestObject) i.next();
135: String key = to.getId();
136: if (!res.containsKey(key)) {
137: res.put(key, new Long(0));
138: } else {
139: long v = ((Long) res.get(key)).longValue();
140: res.put(key, new Long(++v));
141: }
142: }
143: throw new AssertionError("" + res);
144: }
145: }
146: }
147:
148: public static void visitL1DSOConfig(ConfigVisitor visitor,
149: DSOClientConfigHelper config) {
150: new CyclicBarrierSpec().visit(visitor, config);
151: String testClassName = TransparentVectorTestApp.class.getName();
152: config.addRoot(new Root(testClassName, "vector", "vector"),
153: true);
154: config.addRoot(new Root(testClassName, "subList", "subList"),
155: true);
156: config.addRoot(new Root(testClassName, "barrier", "barrier"),
157: true);
158: String methodExpression = "* " + testClassName + ".*(..)";
159: System.err.println("Adding autolock for: " + methodExpression);
160: config.addWriteAutolock(methodExpression);
161: config.addIncludePattern(TestObject.class.getName());
162: }
163:
164: static class TestObject {
165: private String id;
166: private int count;
167:
168: TestObject(String id, int count) {
169: this .id = id;
170: this .count = count;
171: }
172:
173: public String getId() {
174: return id;
175: }
176:
177: public String toString() {
178: return "TestObject(" + id + "," + count + ")";
179: }
180: }
181:
182: }
|