001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tctest;
006:
007: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
008:
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.util.ReadOnlyException;
013: import com.tc.simulator.app.ApplicationConfig;
014: import com.tc.simulator.listener.ListenerProvider;
015: import com.tc.util.Assert;
016: import com.tc.util.DebugUtil;
017: import com.tctest.restart.system.ObjectDataTestApp;
018: import com.tctest.runner.AbstractTransparentApp;
019:
020: import java.util.HashMap;
021: import java.util.Iterator;
022: import java.util.LinkedHashMap;
023: import java.util.Map;
024: import java.util.Set;
025:
026: public class LinkedHashMapTestApp extends AbstractTransparentApp {
027: public static final String SYNCHRONOUS_WRITE = "synch-write";
028:
029: private final MapRoot root = new MapRoot();
030:
031: private final CyclicBarrier barrier;
032:
033: public LinkedHashMapTestApp(String appId, ApplicationConfig cfg,
034: ListenerProvider listenerProvider) {
035: super (appId, cfg, listenerProvider);
036: barrier = new CyclicBarrier(getParticipantCount());
037: }
038:
039: public void run() {
040: try {
041: putTesting();
042: getTesting();
043: getROTesting();
044: unsharedGetTesting();
045: } catch (Throwable t) {
046: notifyError(t);
047: }
048: }
049:
050: private void clear() throws Exception {
051: synchronized (root) {
052: root.clear();
053: }
054: barrier.barrier();
055: }
056:
057: private void initialize() throws Exception {
058: synchronized (root) {
059: if (root.getIndex() == 0) {
060: root.getMap().putAll(getInitialMapData());
061: root.setIndex(root.getIndex() + 1);
062: }
063: }
064: barrier.barrier();
065: }
066:
067: private Map getInitialMapData() {
068: Map map = new HashMap();
069: map.put("January", "Jan");
070: map.put("February", "Feb");
071: map.put("March", "Mar");
072: map.put("April", "Apr");
073: return map;
074: }
075:
076: private void getTesting() throws Exception {
077: clear();
078: initialize();
079:
080: LinkedHashMap map = root.getMap();
081: synchronized (map) {
082: if (root.getIndex() != 0) {
083: map.get("February");
084: map.get("April");
085: root.setIndex(0);
086: }
087: }
088:
089: barrier.barrier();
090:
091: LinkedHashMap expect = new LinkedHashMap(10, 0.75f, true);
092: expect.putAll(getInitialMapData());
093: expect.get("February");
094: expect.get("April");
095:
096: assertMappings(expect, map);
097:
098: barrier.barrier();
099: }
100:
101: /**
102: * The goal of this test is that it will not throw a ReadOnlyException during the get() operation since the
103: * LinkedHashMap is unshared.
104: */
105: private void unsharedGetTesting() throws Exception {
106: LinkedHashMap map = new LinkedHashMap(10, 0.75f, true);
107: map.putAll(getInitialMapData());
108: map.get("February");
109: map.get("April");
110:
111: barrier.barrier();
112: }
113:
114: private void getROTesting() throws Exception {
115: clear();
116: initialize();
117: try {
118: tryReadOnlyGetTesting();
119: throw new AssertionError(
120: "I should have thrown an ReadOnlyException.");
121: } catch (Throwable t) {
122: if (ReadOnlyException.class.getName().equals(
123: t.getClass().getName())) {
124: // ignore ReadOnlyException in read only tests.
125: } else {
126: throw new RuntimeException(t);
127: }
128: }
129: barrier.barrier();
130: }
131:
132: private void tryReadOnlyGetTesting() {
133: LinkedHashMap map = root.getMap();
134: synchronized (map) {
135: if (root.getIndex() != 0) {
136: map.get("February");
137: map.get("April");
138: root.setIndex(0);
139: }
140: }
141: }
142:
143: private void putTesting() throws Exception {
144: clear();
145: initialize();
146:
147: LinkedHashMap expect = new LinkedHashMap(10, 0.75f, true);
148: expect.putAll(getInitialMapData());
149:
150: assertMappings(expect, root.getMap());
151:
152: barrier.barrier();
153:
154: }
155:
156: void assertMappings(Map expect, Map actual) {
157: Assert.assertEquals(expect.size(), actual.size());
158:
159: Set expectEntries = expect.entrySet();
160: Set actualEntries = actual.entrySet();
161: for (Iterator iExpect = expectEntries.iterator(), iActual = actualEntries
162: .iterator(); iExpect.hasNext();) {
163: Assert.assertEquals(iExpect.next(), iActual.next());
164: }
165: }
166:
167: public static void visitL1DSOConfig(ConfigVisitor visitor,
168: DSOClientConfigHelper config) {
169: visitL1DSOConfig(visitor, config, new HashMap());
170: }
171:
172: public static void visitL1DSOConfig(ConfigVisitor visitor,
173: DSOClientConfigHelper config, Map optionalAttributes) {
174: DebugUtil.DEBUG = true;
175:
176: boolean isSynchronousWrite = false;
177: if (optionalAttributes.size() > 0) {
178: isSynchronousWrite = Boolean.valueOf(
179: (String) optionalAttributes
180: .get(ObjectDataTestApp.SYNCHRONOUS_WRITE))
181: .booleanValue();
182: }
183:
184: TransparencyClassSpec spec = config
185: .getOrCreateSpec(CyclicBarrier.class.getName());
186: addWriteAutolock(config, isSynchronousWrite, "* "
187: + CyclicBarrier.class.getName() + "*.*(..)");
188:
189: String testClass = LinkedHashMapTestApp.class.getName();
190: spec = config.getOrCreateSpec(testClass);
191:
192: config.addIncludePattern(MapRoot.class.getName());
193:
194: String writeAllowdMethodExpression = "* " + testClass
195: + "*.*(..)";
196: addWriteAutolock(config, isSynchronousWrite,
197: writeAllowdMethodExpression);
198: String readOnlyMethodExpression = "* " + testClass
199: + "*.*ReadOnly*(..)";
200: config.addReadAutolock(readOnlyMethodExpression);
201:
202: spec.addRoot("root", "root");
203: spec.addRoot("barrier", "barrier");
204:
205: DebugUtil.DEBUG = false;
206: }
207:
208: private static void addWriteAutolock(DSOClientConfigHelper config,
209: boolean isSynchronousWrite, String methodPattern) {
210: if (isSynchronousWrite) {
211: config.addSynchronousWriteAutolock(methodPattern);
212: debugPrintln("***** doing a synchronous write");
213: } else {
214: config.addWriteAutolock(methodPattern);
215: }
216: }
217:
218: private static void debugPrintln(String s) {
219: if (DebugUtil.DEBUG) {
220: System.err.println(s);
221: }
222: }
223:
224: private static class MapRoot {
225: private final LinkedHashMap map = new LinkedHashMap(10, 0.75f,
226: true);
227: private int index;
228:
229: public MapRoot() {
230: index = 0;
231: }
232:
233: public int getIndex() {
234: return index;
235: }
236:
237: public void setIndex(int index) {
238: this .index = index;
239: }
240:
241: public LinkedHashMap getMap() {
242: return map;
243: }
244:
245: public void clear() {
246: map.clear();
247: index = 0;
248: }
249: }
250: }
|