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.tc.objectserver.managedobject;
005:
006: import com.tc.object.ObjectID;
007: import com.tc.objectserver.core.api.TestDNACursor;
008: import com.tc.objectserver.managedobject.bytecode.ClassNotCompatableException;
009: import com.tc.objectserver.persistence.impl.InMemoryPersistor;
010:
011: import java.util.Collection;
012: import java.util.HashMap;
013: import java.util.HashSet;
014: import java.util.Iterator;
015: import java.util.Map;
016: import java.util.Set;
017:
018: import junit.framework.TestCase;
019:
020: public class ManagedObjectStateTest extends TestCase {
021:
022: private ObjectID objectID;
023: private ManagedObjectChangeListenerProvider listenerProvider;
024:
025: public void setUp() throws Exception {
026: objectID = new ObjectID(2002);
027: listenerProvider = new NullManagedObjectChangeListenerProvider();
028: }
029:
030: public void testPhysicalManagedObjectClassId() throws Exception {
031: String loaderDesc = "System.loader";
032:
033: ManagedObjectStateFactory.disableSingleton(true);
034: ManagedObjectStateFactory.createInstance(listenerProvider,
035: new InMemoryPersistor());
036:
037: HashMap types = new HashMap();
038: types.put("field1", new ObjectID(1));
039: types.put("field2", new Boolean(true));
040: types.put("field3", new Character('c'));
041: types.put("field4", new Long(5));
042: types.put("field5", new Integer(15));
043: types.put("field6", new String("neoistheone"));
044: types.put("field7", new Short((short) 606));
045: types.put("field8", new Double(98.76d));
046: types.put("field9", new Float(8.8f));
047: // Not supported in 1.4
048: // types.put("field10", new StackTraceElement("classname", "methodname", "filename", 123));
049:
050: TestDNACursor cursor = new TestDNACursor();
051: for (Iterator i = types.entrySet().iterator(); i.hasNext();) {
052: Map.Entry element = (Map.Entry) i.next();
053: cursor.addPhysicalAction((String) element.getKey(), element
054: .getValue());
055: }
056:
057: int numOfGeneratedClasses = 10000;
058: Map classNameToClassId = new HashMap();
059: Map classIdToClassName = new HashMap();
060:
061: for (int i = 0; i < numOfGeneratedClasses; i++) {
062: String className = "com.xxx.SomeClassName" + i;
063: PhysicalManagedObjectState state = (PhysicalManagedObjectState) ManagedObjectStateFactory
064: .getInstance().createState(new ObjectID(1),
065: ObjectID.NULL_ID, className, loaderDesc,
066: cursor);
067: state.apply(objectID, cursor, new BackReferences());
068:
069: int classId = state.getClassId();
070: assertTrue(classId != 0);
071: assertEquals(state.getClassName(), className);
072: assertEquals(state.getLoaderDescription(), loaderDesc);
073:
074: classNameToClassId.put(className, new Integer(classId));
075: assertNull(classIdToClassName.get(new Integer(classId)));
076: classIdToClassName.put(new Integer(classId), className);
077: }
078:
079: for (int i = 0; i < numOfGeneratedClasses; i++) {
080: String className = "com.xxx.SomeClassName" + i;
081: PhysicalManagedObjectState state = (PhysicalManagedObjectState) ManagedObjectStateFactory
082: .getInstance().createState(new ObjectID(1),
083: ObjectID.NULL_ID, className, loaderDesc,
084: cursor);
085: state.apply(objectID, cursor, new BackReferences());
086:
087: int classId = state.getClassId();
088:
089: Integer storedClassId = (Integer) classNameToClassId
090: .get(className);
091: assertEquals(classId, storedClassId.intValue());
092:
093: String storedClassName = (String) classIdToClassName
094: .get(new Integer(classId));
095: assertEquals(className, storedClassName);
096:
097: }
098: }
099:
100: public void testPhysicalManagedObjectState() throws Exception {
101: String loaderDesc = "System.loader";
102:
103: ManagedObjectStateFactory.disableSingleton(true);
104: ManagedObjectStateFactory.createInstance(listenerProvider,
105: new InMemoryPersistor());
106:
107: HashMap types = new HashMap();
108: types.put("field1", new ObjectID(1));
109: types.put("field2", new Boolean(true));
110: types.put("field3", new Character('c'));
111: types.put("field4", new Long(5));
112: types.put("field5", new Integer(15));
113: types.put("field6", new String("neoistheone"));
114: types.put("field7", new Short((short) 606));
115: types.put("field8", new Double(98.76d));
116: types.put("field9", new Float(8.8f));
117: // Not supported in 1.4
118: // types.put("field10", new StackTraceElement("classname", "methodname", "filename", 123));
119:
120: TestDNACursor cursor = new TestDNACursor();
121: for (Iterator i = types.entrySet().iterator(); i.hasNext();) {
122: Map.Entry element = (Map.Entry) i.next();
123: cursor.addPhysicalAction((String) element.getKey(), element
124: .getValue());
125: }
126:
127: PhysicalManagedObjectState state = (PhysicalManagedObjectState) ManagedObjectStateFactory
128: .getInstance().createState(new ObjectID(1),
129: ObjectID.NULL_ID, "com.xxx.SomeClassName",
130: loaderDesc, cursor);
131: state.apply(objectID, cursor, new BackReferences());
132:
133: assertTrue(state.getClassId() != 0);
134: assertEquals(state.getClassName(), "com.xxx.SomeClassName");
135: assertEquals(state.getLoaderDescription(), loaderDesc);
136:
137: Collection references = state.getObjectReferences();
138: assertEquals(1, references.size());
139: assertEquals(new ObjectID(1), references.iterator().next());
140:
141: Map values = state.addValues(new HashMap());
142: assertEquals(types.size(), values.size());
143: assertEquals(new ObjectID(1), values.get("field1"));
144:
145: Boolean l2 = (Boolean) values.get("field2");
146: assertTrue(l2.booleanValue());
147: Character f3 = (Character) values.get("field3");
148: assertEquals(f3.charValue(), 'c');
149:
150: System.err.println("values =" + values);
151: assertEquals(types, values);
152:
153: cursor = new TestDNACursor();
154: cursor.addPhysicalAction("field1", new ObjectID(2));
155: cursor.addPhysicalAction("field2", new Boolean(false));
156: cursor.addPhysicalAction("field3", new Character('d'));
157:
158: state.apply(objectID, cursor, new BackReferences());
159:
160: references = state.getObjectReferences();
161: assertEquals(1, references.size());
162: assertEquals(new ObjectID(2), references.iterator().next());
163:
164: values = state.addValues(new HashMap());
165: assertEquals(types.size(), values.size());
166: assertEquals(new ObjectID(2), values.get("field1"));
167:
168: l2 = (Boolean) values.get("field2");
169: assertFalse(l2.booleanValue());
170: f3 = (Character) values.get("field3");
171: assertEquals(f3.charValue(), 'd');
172:
173: assertEquals(ObjectID.NULL_ID, state.getParentID());
174: }
175:
176: public void testPhysicalMOStateClassInCompatibility()
177: throws Exception {
178: String loaderDesc = "System.loader";
179:
180: InMemoryPersistor persistor = new InMemoryPersistor();
181: ManagedObjectStateFactory.disableSingleton(true);
182: ManagedObjectStateFactory.createInstance(listenerProvider,
183: persistor);
184:
185: TestDNACursor cursor = new TestDNACursor();
186: cursor.addPhysicalAction("field1", new ObjectID(1));
187: cursor.addPhysicalAction("field2", new Long(11));
188: cursor.addPhysicalAction("field3", new String("neoistheone"));
189:
190: PhysicalManagedObjectState state = (PhysicalManagedObjectState) ManagedObjectStateFactory
191: .getInstance().createState(objectID, ObjectID.NULL_ID,
192: "com.xxx.SomeClassName", loaderDesc, cursor);
193: state.apply(objectID, cursor, new BackReferences());
194:
195: assertTrue(state.getClassId() != 0);
196: assertEquals(state.getClassName(), "com.xxx.SomeClassName");
197: assertEquals(state.getLoaderDescription(), loaderDesc);
198:
199: Collection references = state.getObjectReferences();
200: assertEquals(1, references.size());
201: assertEquals(new ObjectID(1), references.iterator().next());
202:
203: Map values = state.addValues(new HashMap());
204: assertEquals(3, values.size());
205: assertEquals(new ObjectID(1), values.get("field1"));
206:
207: Long l2 = (Long) values.get("field2");
208: assertEquals(11, l2.longValue());
209: String f3 = (String) values.get("field3");
210: assertEquals(f3, "neoistheone");
211:
212: cursor = new TestDNACursor();
213: cursor.addPhysicalAction("field1", new ObjectID(2));
214: // Newly added fields
215: cursor.addPhysicalAction("field4", new Boolean(false));
216: cursor.addPhysicalAction("field5", new ObjectID(22));
217:
218: try {
219: state.apply(objectID, cursor, new BackReferences());
220: assertTrue(false);
221: } catch (ClassNotCompatableException cfe) {
222: // expected
223: }
224:
225: // recreate the state object
226: PhysicalManagedObjectState state1 = (PhysicalManagedObjectState) ManagedObjectStateFactory
227: .getInstance().recreateState(objectID,
228: ObjectID.NULL_ID, "com.xxx.SomeClassName",
229: loaderDesc, cursor, state);
230: state1.apply(objectID, cursor, new BackReferences());
231:
232: assertTrue(state1.getClassId() != state.getClassId());
233: assertEquals(state1.getClassName(), "com.xxx.SomeClassName");
234: assertEquals(state1.getLoaderDescription(), loaderDesc);
235:
236: references = state1.getObjectReferences();
237: assertEquals(2, references.size());
238: Set expectedRefs = new HashSet();
239: expectedRefs.add(new ObjectID(2));
240: expectedRefs.add(new ObjectID(22));
241:
242: values = state1.addValues(new HashMap());
243: assertEquals(new ObjectID(2), values.get("field1"));
244: l2 = (Long) values.get("field2");
245: assertEquals(11, l2.longValue());
246: f3 = (String) values.get("field3");
247: assertEquals(f3, "neoistheone");
248: Boolean f4 = (Boolean) values.get("field4");
249: assertEquals(f4, new Boolean(false));
250: assertEquals(new ObjectID(22), values.get("field5"));
251:
252: // Now try applying yet another new field on the old object
253: TestDNACursor cursor2 = new TestDNACursor();
254: cursor2.addPhysicalAction("field6", new Integer(2), false);
255:
256: try {
257: state.apply(objectID, cursor2, new BackReferences());
258: assertTrue(false);
259: } catch (ClassNotCompatableException cfe) {
260: // expected
261: }
262:
263: // recreate the state object, even though we pass old state object, it should extend latest state object
264: PhysicalManagedObjectState state2 = (PhysicalManagedObjectState) ManagedObjectStateFactory
265: .getInstance().recreateState(objectID,
266: ObjectID.NULL_ID, "com.xxx.SomeClassName",
267: loaderDesc, cursor2, state);
268: state2.apply(objectID, cursor2, new BackReferences());
269: cursor.reset();
270: state2.apply(objectID, cursor, new BackReferences());
271:
272: assertTrue(state1.getClassId() != state2.getClassId());
273: assertEquals(state2.getClassName(), "com.xxx.SomeClassName");
274: assertEquals(state2.getLoaderDescription(), loaderDesc);
275:
276: values = state2.addValues(new HashMap());
277: assertEquals(new ObjectID(2), values.get("field1"));
278: l2 = (Long) values.get("field2");
279: assertEquals(11, l2.longValue());
280: f3 = (String) values.get("field3");
281: assertEquals(f3, "neoistheone");
282: f4 = (Boolean) values.get("field4");
283: assertEquals(f4, new Boolean(false));
284: assertEquals(new ObjectID(22), values.get("field5"));
285: Integer i6 = (Integer) values.get("field6");
286: assertEquals(2, i6.intValue());
287:
288: assertEquals(state1.getClass().getName(), state2.getClass()
289: .getSuperclass().getName());
290:
291: // The same field is changed from Integer to Long, this is not support.
292: cursor2 = new TestDNACursor();
293: cursor2.addPhysicalAction("field6", new Long(2));
294: try {
295: // We print the exception but dont throw it.
296: state2.apply(objectID, cursor2, new BackReferences());
297: System.err.println("The above exception is NORMAL.");
298: } catch (ClassCastException cfe) {
299: assertTrue(false);
300: }
301:
302: values = state2.addValues(new HashMap());
303: i6 = (Integer) values.get("field6");
304: assertEquals(2, i6.intValue());
305:
306: // Try to create a new State Object
307: cursor = new TestDNACursor();
308: cursor.addPhysicalAction("field1", new ObjectID(1));
309: cursor.addPhysicalAction("field2", new Long(11));
310: cursor.addPhysicalAction("field3", new String("neoistheone"));
311:
312: PhysicalManagedObjectState state3 = (PhysicalManagedObjectState) ManagedObjectStateFactory
313: .getInstance().createState(objectID, ObjectID.NULL_ID,
314: "com.xxx.SomeClassName", loaderDesc, cursor);
315: state3.apply(objectID, cursor, new BackReferences());
316: assertEquals(state2.getClass().getName(), state3.getClass()
317: .getName());
318:
319: // RESTART Scenario... still only the new object type should be used
320: cursor.reset();
321: ManagedObjectStateFactory.createInstance(listenerProvider,
322: persistor);
323: state3 = (PhysicalManagedObjectState) ManagedObjectStateFactory
324: .getInstance().createState(objectID, ObjectID.NULL_ID,
325: "com.xxx.SomeClassName", loaderDesc, cursor);
326: state3.apply(objectID, cursor, new BackReferences());
327: assertEquals(state2.getClass().getName(), state3.getClass()
328: .getName());
329:
330: assertEquals(ObjectID.NULL_ID, state.getParentID());
331: }
332:
333: }
|