001: /*
002: * All content copyright (c) 2003-2007 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 com.tc.object.bytecode.Clearable;
008: import com.tc.object.bytecode.Manageable;
009: import com.tc.object.bytecode.TCMap;
010: import com.tc.object.config.ConfigVisitor;
011: import com.tc.object.config.DSOClientConfigHelper;
012: import com.tc.object.config.TransparencyClassSpec;
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.runtime.Vm;
017: import com.tctest.runner.AbstractErrorCatchingTransparentApp;
018:
019: import java.util.ArrayList;
020: import java.util.Collection;
021: import java.util.HashMap;
022: import java.util.Hashtable;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026: import java.util.Map.Entry;
027:
028: public class ClearableTest extends TransparentTestBase {
029:
030: public void doSetUp(TransparentTestIface t) throws Exception {
031: t.getTransparentAppConfig().setClientCount(1);
032: t.initializeTestRunner();
033: }
034:
035: protected Class getApplicationClass() {
036: return App.class;
037: }
038:
039: private static Map makeCHM() throws Exception {
040: return (Map) Class.forName(
041: "java.util.concurrent.ConcurrentHashMap").newInstance();
042: }
043:
044: public static class App extends AbstractErrorCatchingTransparentApp {
045:
046: private static final int NUM = 100;
047: private final List clearables = new ArrayList();
048:
049: public App(String appId, ApplicationConfig cfg,
050: ListenerProvider listenerProvider) {
051: super (appId, cfg, listenerProvider);
052: }
053:
054: protected void runTest() throws Throwable {
055: add(new HashMap());
056: add(new Hashtable());
057:
058: if (Vm.isJDK15Compliant()) {
059: add(makeCHM());
060: }
061:
062: for (Iterator i = clearables.iterator(); i.hasNext();) {
063: Clearable c = (Clearable) i.next();
064:
065: // At the time this test was written, all Clearable types should have eviction enabled by default
066: // (ie. one should not need to manually enable eviction)
067: if (!c.isEvictionEnabled()) {
068: throw new RuntimeException(c.getClass()
069: + " does not have eviction enabled");
070: }
071:
072: populate(c);
073: clear(c);
074: validateCleared(c);
075: }
076: }
077:
078: private void validateCleared(Clearable c) {
079: if (c instanceof TCMap) {
080: Collection local = ((TCMap) c)
081: .__tc_getAllLocalEntriesSnapshot();
082: Assert.assertEquals(c.getClass(), 0, local.size());
083:
084: for (Iterator i = ((Map) c).entrySet().iterator(); i
085: .hasNext();) {
086: Map.Entry entry = (Entry) i.next();
087: Key k = (Key) entry.getKey();
088: Value v = (Value) entry.getValue();
089: Assert.assertEquals(k.getI(), v.getI());
090: }
091:
092: } else {
093: throw new RuntimeException(
094: "no validateCleared support for "
095: + c.getClass());
096: }
097: }
098:
099: private void clear(Clearable c) {
100: if (c instanceof Map) {
101: Map m = (Map) c;
102: for (Iterator i = m.values().iterator(); i.hasNext();) {
103: ((Manageable) i.next()).__tc_managed()
104: .clearAccessed();
105: }
106:
107: int numToClear = m.size();
108: int cleared = c.__tc_clearReferences(numToClear);
109: Assert.assertEquals(c.getClass(), numToClear, cleared);
110: } else {
111: throw new RuntimeException("no clear support for "
112: + c.getClass());
113: }
114: }
115:
116: private void populate(Object o) {
117: if (o instanceof Map) {
118: synchronized (o) {
119: for (int i = 0; i < NUM; i++) {
120: ((Map) o).put(new Key(i), new Value(i));
121: }
122: }
123: } else {
124: throw new RuntimeException("no populate support for "
125: + o.getClass());
126: }
127: }
128:
129: private void add(Object clearable) {
130: if (!(clearable instanceof Clearable)) {
131: throw new RuntimeException(clearable.getClass()
132: + " is not Clearable!");
133: }
134: synchronized (clearables) {
135: clearables.add(clearable);
136: }
137: }
138:
139: public static void visitL1DSOConfig(ConfigVisitor visitor,
140: DSOClientConfigHelper config) {
141: String testClassName = App.class.getName();
142: TransparencyClassSpec spec = config
143: .getOrCreateSpec(testClassName);
144: spec.addRoot("clearables", "clearables");
145: String methodExpression = "* " + testClassName + "*.*(..)";
146: config.addWriteAutolock(methodExpression);
147:
148: config.addIncludePattern(Key.class.getName());
149: config.addIncludePattern(Value.class.getName());
150: }
151:
152: }
153:
154: private static class Key {
155:
156: private final int i;
157:
158: Key(int i) {
159: this .i = i;
160: }
161:
162: int getI() {
163: return i;
164: }
165:
166: public int hashCode() {
167: return i;
168: }
169:
170: public boolean equals(Object obj) {
171: if (obj instanceof Key) {
172: return this .i == ((Key) obj).i;
173: }
174: return false;
175: }
176:
177: }
178:
179: private static class Value {
180:
181: private final int i;
182:
183: Value(int i) {
184: this .i = i;
185: }
186:
187: int getI() {
188: return i;
189: }
190:
191: }
192:
193: }
|